Lalit Goyal
Lalit Goyal

Reputation: 61

Spring Transaction Management to rollback the checked exception

i am working on the Spring "@Transactional" Annotation to handle the transaction.

   @Transactional(readOnly = false,propagation=Propagation.REQUIRES_NEW,isolation=Isolation.READ_UNCOMMITTED,rollbackFor=SQLException.class)
public void updateBatch(Report a)
        throws SQLException, DataAccessException { insert1();insert2(); insert3(); }

But in case

these inserts are ibatis inbuild functions to trigger the insert in DB I got the following exception

"Caused by: org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:717)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)"

And the transaction would not get rolledback i.e. insert1(),insert2() does not get rollback

Please do let me know what i am missing

Upvotes: 1

Views: 10040

Answers (1)

instanceOfObject
instanceOfObject

Reputation: 2984

What are you doing in insert1 and insert2?

Are they using another transaction with PROPAGATION.REQUIRES_NEW attribute? If yes, they will not be rolled back. Else are you rolling back in insert1 or insert2?

I've experienced the same problem. Though it might be a bit different as the one you have. What I've had was a situation where you've got two services A and B.

A is calling a method of B in a try-catch block. B throws RuntimeException and the catch block of A wraps that exception into a catched exception.

What happened in my scenario: - B is a separate class behind a transaction proxy - B throws a runtime exception which sets transaction to rollback - as I have Propagation.REQUIERED, it is the same transaction as the one for the method of A - A wraps the exception and throws it as the exception is neither RuntimeException nor Error, the mention method will not proceed into transactionManager.rollback but to transactionManager.commit - that would throw the UnexpectedRollback as the transaction was previously marked as rollback.

Your case might be different.

Upvotes: 2

Related Questions