Transaction and Email

Consideration of a general use case for a user creating a new account in a web application, and an application sending a confirmation email to a user’s address. From what I saw, this is usually implemented in one of three ways:

  • The web controller calls the service method, which creates a user account and sends the email as part of a single transaction.
  • The web controller calls the service method (with tx = never propagation), which calls the 1st method to create the user account in the transaction, and then calls the second method to send the email.
  • The web controller calls the 1st service method, which creates the user account in the transaction, and then the second service method, which sends the email.

The 1st approach is simple and simple, but there is a risk that the transaction will be canceled after sending the email message, thereby invalidating the message. The second approach is more complex, but it ensures that the letter is sent only if the user’s creation really succeeded. The 3rd approach is simple, but burdens the web tier with business logic that he does not need to know about.

Is there a simpler approach, possibly managed by AOP, that ensures that an email will only be sent if the user create transaction really succeeds? Am I paranoid in thinking that the first approach may fail?

We use the Java EE + Spring stack and are ready to integrate additional APIs (AOP? Spring Integration?) To achieve this.

Hooray!

+4
source share
4 answers

Another opportunity I'm currently using to solve this problem:

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

+6
source

To send emails, it is recommended that you use priority and send emails to be sent, like every 5 or 15 minutes. The queue will be stored in the database, therefore inside the transaction. Then plan the procedure for sending email from this queue at regular intervals.

The only way I found to make sure that the message was sent only when the transaction is completed and completed, because by definition the email addresses are not tied to any database transactions.

+5
source

I would add a lightweight JMS layer, such as ActiveMQ for email, it's pretty easy to configure and integrate (and even implement) using Spring. Then you have

1) The operation of creating a user and sending a JMS message in 1 transaction. If you fail, you are still in good condition (both commit or both rollbacks, and you present the error to the user)

2) If the JMS consumer cannot send the email, you can configure the JMS queue to retry several times, and you will have the best solution to manage transient issues in your email system.

0
source

A queue with a database table and starting a scheduling program using Quartz or something that is reasonable and easy to implement.

It's also nice to use RabbitMQ to develop these features. RabbitMQ is quite simple to configure and can be used for most cases for interaction between exchange / subscription systems, even if you may need to implement the application level and small applications that sign messages from RabbitMQ and send e-mail via SMTP.

This may seem redundant, but you can use this solution # 2 for every system that requires sending emails in the future. You can still use the queue-based database model, but an expensive cpu / resources data source will be used to send emmail.

0
source

All Articles