Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring nested @Transactional method and rollback

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?

like image 971
JayPea Avatar asked Nov 09 '11 20:11

JayPea


1 Answers

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.

like image 65
dmansfield Avatar answered Nov 15 '22 09:11

dmansfield