I’m using Postgres and have a transactional method defined as follows:
@Entity
public class SomeEntity {
// …
}
@Transactional(isolation = READ_COMMITED)
public void persistUniqueAndSendEmail() {
SomeEntity e = // …
// Persis the entity to Postgres with a unique constraint that may fail
// Once the entity is persisted send the notification email
}
With READ_COMMITED isolation level is it possible that the unique constraint violation is thrown when the transaction is actually committed, not the actual sql statement is executed?
If so that would mean that the email can be sent, but the relevant changes are not persisted.
The transaction doesnt finish until the end of the method. The save doesnt flush until the transaction finishing prompts it to. So yes, you could get a constraint violation that rolls back the save after the email is sent.
You could try calling saveAndFlush instead of save (see Difference between save and saveAndFlush in Spring data jpa). The flush forces the database call to occur, which will trigger any constraint violation (even while the transaction is still in progress).
But you don't want the transaction to fail for some other reason and have the email sent erroneously, and there are plenty of ways that can happen. The safe thing to do (well, a relatively safer way) is make sure the transaction completes successfully, then send the email either in another service calling the transactional service, or in an AOP interceptor.
That way is safe for the database work, but is not safe for the email-sending, because as this answer points out thoroughly, you do have a 2-system problem. It's worth thinking about what happens in your posted code when your transaction rolls back, and the email still gets sent. If you want your transaction to be repeated you have to send the email again. Mixing non-transactional stuff like email in with transactional database updates is fraught with peril.
Check your requirements, find out the consequences of failing to send an email, or of sending duplicate emails, and use that information to decide how much trouble to go to coordinating these two systems.