Bare fordi du kan, betyder det ikke, at du skal. Der er bedre måder at gøre dette på. Gør det ikke direkte fra en PL. Hvis du vil ignorere mine advarsler, så brug PL/PerlU og skriv det, som du ville gøre med enhver anden e-mail-klient. Du kan bruge ethvert CPAN-modul, du kan lide, som gør dit liv lettere.
To grunde til ikke at:
1) Hvad hvis din transaktion afbrydes/ruller tilbage? Du har sendt e-mailen, men ikke foretaget tilsvarende ændringer i db. Du laver ikke-transaktionelle ting i en transaktion.
2) Hvad hvis din e-mail hænger og venter på svar, indtil du får en tcp-timeout efter 2 min? Kommer du til at glemme at sende en e-mail til kunden? Afbryde transaktionen (kan ikke sende e-mail, kan ikke sige, at vi har afsendt delen!)?
Dette er en dårlig ide. Gør det ikke. Tak PostgreSQL for denne fejl og flyt den ud i en anden dæmon.
En meget bedre tilgangen er at bruge LISTEN og NOTIFY og tabeller i kø. Du kan derefter oprette en tabel som denne:
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$;
Få derefter din lagrede procedure indsat i den tabel.
Derefter skal du have en anden klient-app, som LISTEN på emails_waiting listens (sql-sætning LISTEN emails_waiting
) og gør derefter som følger:
- Tjekker, om der er poster i email_queue. Hvis ikke, gå til 3.
- læser data, sender e-mail, sletter posten og forpligter.
- Når køen er tom, sover i x sekunder
- Ved opvågning tjekker du for asynkron. meddelelser (afhænger af klientbiblioteker, tjek dokumenter). Hvis der er, skal du gå til 1, hvis ikke, gå til 3.
Dette gør det muligt for dine e-mails at blive sat i kø til afsendelse af din transaktion og for at denne automatisk sendes til en anden applikation, som derefter kan oprette forbindelse til MTA'en, hvis du ønsker det.
Den anden klientapp kan skrives på det sprog, du vælger, ved hjælp af de værktøjer, du kender. Det har fordelen ved at gøre alle netværksting ud af transaktionen, så hvis du sender via en anden SMTP-server, og forbindelsen hænger, venter hele din databasetransaktion ikke i 2 minutter på, at den får timeout og afbryde transaktionen . Det er dermed også sikrere mod fremtidige ændringer i krav.