/ / Transazione e invio di un'e-mail: java, spring, email, transazioni

Transazione e invio di un'e-mail: java, spring, email, transazioni

Considerando il caso di uso comune di un utentecreando un nuovo account su un'applicazione web e l'applicazione inviando un'email di conferma all'indirizzo dell'utente. Da quello che ho visto, questo è tipicamente implementato in uno dei 3 modi seguenti:

  1. Il controller Web chiama un metodo di servizio, che crea l'account utente e invia l'e-mail, entrambi in un'unica transazione.
  2. Il controller Web chiama un metodo di servizio (contx propagation = never), che invoca un primo metodo su se stesso per creare l'account utente all'interno di una transazione, e quindi invoca un secondo metodo su se stesso per inviare l'e-mail.
  3. Il controller Web chiama un primo metodo di servizio, che crea l'account utente all'interno di una transazione, quindi un secondo metodo di servizio che invia l'e-mail.

Il primo approccio è semplice e diretto,ma c'è il rischio che la transazione venga ripristinata dopo l'invio dell'e-mail, rendendo quindi l'e-mail non valida. Il secondo approccio è più complicato, ma garantisce che l'e-mail sia inviata solo se la creazione dell'utente è effettivamente riuscita. Il 3 ° approccio è semplice ma opprime il livello web con una logica aziendale che non dovrebbe essere necessario conoscere.

Non c'è un approccio più semplice, magari guidato da AOP,ciò garantisce che l'email verrà inviata solo se la transazione di creazione dell'utente è effettivamente riuscita? Sono paranoico nel pensare che il primo approccio potrebbe fallire?

Stiamo usando uno stack Java EE + Spring e siamo disposti ad integrare API aggiuntive (AOP? Spring Integration?) Per raggiungere questo obiettivo.

Saluti!

risposte:

6 per risposta № 1

Un'altra opzione che sto attualmente utilizzando per risolvere questo problema:

http://download.oracle.com/javaee/6/api/javax/transaction/Synchronization.html


5 per risposta № 2

Per inviare e-mail, si consiglia di utilizzare una codae pianifica le email da inviare come ogni 5 o 15 minuti. La coda verrà archiviata nel database, quindi all'interno della transazione. Quindi pianificare una procedura per inviare e-mail da quella coda a intervalli regolari.

È l'unico modo per accertarmi che l'e-mail sia inviata solo quando la transazione è completata e impegnata, poiché le e-mail per definizione non sono legate a nessun tipo di transazioni di database.


0 per risposta № 3

Aggiungerei un leggero strato JMS come ActiveMQ per l'e-mail, è piuttosto facile da configurare e integrare (e persino incorporare) con Spring. Allora hai

1) Transazione di creazione utente e invio di messaggi JMS in 1 transazione. Se uno dei due fallisce, sei ancora in buono stato (sia commit sia rollback e tu presenti un errore all'utente)

2) Se il consumatore JMS non riesce a inviare l'e-mail, è possibile impostare la coda JMS per riprovare alcune volte e si avrà una soluzione migliore per la gestione dei problemi transitori con il proprio sistema di posta elettronica.


0 per risposta № 4

Fare la coda con la tabella del database ed eseguire il programma di pianificazione con Quartz o qualcosa di simile dovrebbe essere ragionevole e facile da implementare.

È anche una buona idea usare RabbitMQ per quellisviluppo di funzionalità. RabbitMQ è abbastanza facile da configurare e può essere utilizzato per la maggior parte dei casi per l'interazione tra i sistemi di pubblicazione / sottoscrizione anche se potrebbe essere necessario implementare ack a livello di applicazione e piccole app che sottoscrivono messaggi da RabbitMQ e invia e-mail tramite SMTP.

Può sembrare eccessivo, ma puoi usare questo # 2soluzione per ogni sistema che richiede l'invio di e-mail in futuro. È comunque possibile utilizzare il modello basato sulla coda di database per questo, ma utilizzerà costose cpu / risorse di database per inviare emmail.