1

Currently we are facing a spring transaction related issue in our application. As you can see that in deleteRecord() we are doing a DB operation. But in the next line a business exception is thrown.

Expected Behavior(As per my knowledge) : The DB operation should be rolled back as exception is thrown from the next line

Actual Behavior : Its not getting rolled back. Data is getting inserted to the table

Question : Why transaction is not getting rolled back ? I dont think its because of the catch block because deleteRecord() will be executed in new transaction. Please correct me if I am wrong

Code:

class A {
    void myMethod() {
        for(int i=0 ; i<count ; i++) {
            try {
                    deleteRecord();
                } catch(Exception e) {
                    log.error("Exception caught");

                }

        }

}

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    deleteRecord() throws Exception{
        line 1 : deleting record 
        line 2 : Throwing business exception 

    }
}
Rahman
  • 3,755
  • 3
  • 26
  • 43

3 Answers3

2

The Spring documentation says the following:

While the EJB default behavior is for the EJB container to automatically roll back the transaction on a system exception (usually a runtime exception), EJB CMT does not roll back the transaction automatically on an application exception (that is, a checked exception other than java.rmi.RemoteException). While the Spring default behavior for declarative transaction management follows EJB convention (roll back is automatic only on unchecked exceptions), it is often useful to customize this.

And

In its default configuration, the Spring Framework’s transaction infrastructure code only marks a transaction for rollback in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException. ( Errors will also - by default - result in a rollback). Checked exceptions that are thrown from a transactional method do not result in rollback in the default configuration

see in 16.5.3: https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html

This says that the default behavior of the transaction will only rollback for RuntimeExceptions. If you have a own business exception (could be a checked excpetion), you have to explicitly name the exception class the transaction should rollback for:

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = YOUREXCEPTION.class)
rieckpil
  • 10,470
  • 3
  • 32
  • 56
1

change to

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
mahfuj asif
  • 1,691
  • 1
  • 11
  • 32
0

It is because of @Transaction method call by the method within the same class, does not work if you do not configured Spring to use AspectJ.

Spring @Transaction method call by the method within the same class, does not work?

Matej Marconak
  • 1,365
  • 3
  • 20
  • 25