Transaktion und Versand einer E-Mail
In Anbetracht der gemeinsamen Verwendung bei einem Benutzer das erstellen eines neuen Kontos auf eine web-Anwendung und die Anwendung Versendung einer Bestätigungs-E-Mail an die Adresse des Benutzers. Von dem, was ich gesehen habe, das ist in der Regel umgesetzt in eine von 3 Möglichkeiten:
- Der web-controller ruft eine service-Methode, die schafft das Benutzerkonto und sendet die E-Mail-sowohl innerhalb einer einzelnen Transaktion.
- Der web-controller ruft eine service-Methode (mit tx-Vermehrung = nie), die unter Berufung auf einen 1. Methode auf sich selbst, um das Benutzerkonto zu erstellen, die innerhalb einer Transaktion, und startet dann eine 2. Methode auf sich die E-Mail senden.
- Der web-controller ruft eine 1. service-Methode, die schafft das Benutzer-Konto innerhalb einer Transaktion, dann ein 2. service-Methode sendet die E-Mail.
Der 1. Ansatz ist einfach und unkompliziert, aber es gibt ein Risiko, dass die Transaktion ein Rollback ausgeführt wird, nachdem die email gesendet wurde, wodurch die E-Mail ungültig. Der 2. Ansatz ist komplizierter, aber es ist garantiert, dass die E-Mail wird nur gesendet, wenn der Benutzer die Schöpfung ist tatsächlich gelungen. Der 3. Ansatz ist einfach, aber zu Lasten der web-Schicht mit Geschäftslogik, sollte es nicht wissen müssen.
Gibt es nicht einen einfacheren Ansatz, vielleicht AOP-Gefahren, der gewährleistet, dass die E-Mail wird nur gesendet, wenn die Erstellung des Benutzers die Transaktion tatsächlich erfolgreich war? Bin ich paranoid zu denken, dass der 1. Ansatz scheitern könnte?
Verwenden wir Java EE + Spring stack und bereit sind, die Integration von weiteren APIs (AOP? Spring Integration?) um dies zu erreichen.
Prost!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Andere option, die ich momentan verwende um dieses problem zu lösen:
http://download.oracle.com/javaee/6/api/javax/transaction/Synchronization.html
public void sendMailAfterCommit(final MailManager mail) { TransactionSynchronizationManager.registerSynchronization( new TransactionSynchronizationAdapter() { @Override public void afterCommit() { mailService.sendMail(mail); } }); }
E-Mails senden, es wird empfohlen, die Verwendung einer Warteschlange und Zeitplan der E-Mails zu senden, wie alle 5 oder 15 Minuten.
Die Warteschlange wird in der Datenbank gespeichert werden, deshalb innerhalb der Transaktion. Planen Sie eine Prozedur zum senden von E-Mails aus dieser Warteschlange in regelmäßigen Abständen.
Seine die einzige Möglichkeit, die ich gefunden, um sicherzustellen, dass die E-Mail wird nur gesendet, wenn die Transaktion coompleted und engagiert, da E-Mails per definition nicht gebunden an irgendeine Art von Datenbank-Transaktionen.
Ich würde noch ein leichtes JMS-Schicht wie ActiveMQ für die E-Mail-es ist ziemlich einfach zu setup und integriert (und selbst bettet) mit Feder. Dann haben Sie
1) User anlegen Transaktion & senden von JMS-Nachricht geschieht in 1 Transaktion. Wenn entweder nicht, Sie sind noch in einem guten Zustand (beide Begehen oder beide rollback-und Sie präsentieren einen Fehler an den Benutzer)
2) Wenn die JMS-Verbraucher nicht zu senden die E-Mail können Sie die Einstellungen der JMS-Warteschlange zu wiederholen ein paar mal, und du wirst eine bessere Lösung für die Verwaltung von vorübergehenden Problemen mit Ihrem E-Mail-system.
Queuing mit Datenbank-Tabelle, und führen Sie die scheduling-Programm mit Quarz oder so ähnlich sollte angemessen sein und einfach zu implementieren.
Es ist auch eine gute Idee, RabbitMQ für diejenigen, die feature-Entwicklung. RabbitMQ ist ziemlich einfach zu konfigurieren und kann verwendet werden, für die meisten der Fall für publish/subscribe-Interoperabilität zwischen Systemen, auch wenn Sie vielleicht brauchen, zu implementieren application level ack und kleine apps, die abonniert Nachrichten von RabbitMQ und senden E-Mails über SMTP.
Kann es klingt übertrieben, aber Sie können mit diesem #2 Lösung für jedes system, das erfordert, dass E-Mail senden in der Zukunft. Dennoch kann man die Datenbank-queue-Modell für diese, aber teuer-Datenbank cpu-Ressourcen für send-emmail.