Tylko dlatego, że możesz, nie oznacza, że powinieneś. Są na to lepsze sposoby. Nie rób tego bezpośrednio z PL. Jeśli chcesz zignorować moje ostrzeżenia, użyj PL/PerlU i napisz go tak, jak każdy inny klient poczty. Możesz użyć dowolnych modułów CPAN, które ułatwią Ci życie.
Dwa powody, aby nie:
1) Co się stanie, jeśli transakcja zostanie przerwana/cofnięta? Wysłałeś wiadomość e-mail, ale nie wprowadziłeś żadnej zmiany w bazie danych. Robisz rzeczy nietransakcyjne w ramach transakcji.
2) Co się stanie, jeśli poczta e-mail zawiesza się, czekając na odpowiedź, aż po 2 minutach zostanie przekroczony limit czasu tcp? Zapomnisz o wysyłaniu e-maili do klienta? Przerwać transakcję (nie możesz wysłać e-maila, nie możesz powiedzieć, że wysłaliśmy część!)?
To jest złe pomysł. Nie rób tego. Podziękuj PostgreSQL za ten błąd i przenieś go do innego demona.
znacznie lepszy podejściem jest użycie LISTEN i NOTIFY oraz tabel kolejki. Następnie możesz utworzyć taką tabelę:
CREATE TABLE email_queue (
id serial not null unique,
email_from text,
email_to text not null,
body text not null
);
CREATE FUNCTION email_queue_trigger() RETURNS TRIGGER
LANGUAGE PLPGSQL AS $F$
BEGIN
NOTIFY emails_waiting;
END;
$F$;
Następnie wstaw swoją procedurę składowaną do tej tabeli.
Następnie miej drugą aplikację kliencką, która LISTEN nasłuchuje wiadomości e-mail_waiting (instrukcja sql LISTEN emails_waiting
), a następnie wykonuje następujące czynności:
- Sprawdza, czy w kolejce poczty e-mail znajdują się rekordy. Jeśli nie, przejdź do 3.
- odczytuje dane, wysyła e-maile, usuwa rekord i zatwierdza.
- Gdy kolejka jest pusta, śpi przez x sekund
- Po wybudzeniu sprawdza async. powiadomienia (w zależności od bibliotek klienta, sprawdź dokumentację). Jeśli tak, przejdź do 1, jeśli nie, przejdź do 3.
Dzięki temu Twoje wiadomości e-mail mogą być umieszczane w kolejce do wysłania w Twojej transakcji i automatycznie przekazywane do innej aplikacji, która może następnie połączyć się z MTA, jeśli wybierzesz.
Ta druga aplikacja kliencka może być napisana w wybranym przez Ciebie języku, przy użyciu dowolnych narzędzi, które znasz. Ma tę zaletę, że wszystkie operacje sieciowe są usuwane z transakcji, więc jeśli wysyłasz przez drugi serwer SMTP, a połączenie się zawiesza, cała transakcja bazy danych nie czeka przez 2 minuty na przekroczenie limitu czasu i przerwanie transakcji . Jest to również bezpieczniejsze przed przyszłymi zmianami wymagań.