I have a controller that calls a method on a service class which should do the following:
(1) and (2) should be atomic and if both succeed the email should be sent. If I annotate the service method with @Transactional the email is sent even if the DB updates fail (and this is not desired). Furthermore if the email fails the DB update is rolled back (which is not desired either).
My understanding is that moving 3. to a separate method on the same service class would not help. Annotating the sendEmail method with @Transactional and a different propagation behavior (e.g. NEVER or REQUIRES_NEW) does not seem to help either.
Is it possible to achieve the behavior with proper annotations?
You need to have a transaction for the two first steps, then have the transaction committed, and finally send the email. The easiest way to do that is to introduce an additional bean
Controller:
beanA.process();
Bean A:
// not transactional
public void process() {
beanB.updateDatabase();
sendEmail();
}
private void sendEmail() {
...
}
Bean B:
@Transactional
public void updateDatabase() {
dao1.update();
dao2.update();
}