I have a @Service class which has a @Transactional method that calls another @Transactional method on the same class. I was testing rollback behavior for this and I found that it wasn't working properly. The code looks something like this:
@Service
public class DefaulService implements ervice
{
@Transactional
public void methodOne()
{
methodTwo();
//question edited
//this seems to be the problem
this.serviceDAO.executeUpdateOperation();
//test rollback
throw new RuntimeException();
}
@Transactional
public void methodTwo()
{
//DAO stuff
}
}
After running methodOne I check the database and the changes are there, even though the log shows "JDBCTransaction - rollback".
If I call methodTwo individually and add an exception at the end of it, the changes are rolled back correctly.
Is there a way to make methodOne properly rollback changes that occurred during the nested @Transactional call? I was under the impression that the default propagation of REQUIRED would achieve this, but it doesn't seem to be working. Thanks
UPDATE
Ok, I just noticed something else. Right before the exception throw, I'm calling the service's dao and performing a manual update via 'executeUpdate'. If I comment this line, the nested rollback works. So it seems that the problem is actually calling the DAO and running executeUpdate query. But shouldn't this also run inside the current transaction?
You are definitely obtaining the instance of the "ervice" from the bean factory when you call the methods, right? The bean factory needs to set up a proxy which implements the transactional logic around each method call. I was under the impression this only worked when "outsiders" invoke methods via the proxy, and doesn't necessarily work when one method calls another, as that method is a direct call inside the implementation object and does not go via the AOP proxy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With