1
votes

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

  • insert1() - successfully inserts the data in table A.
  • insert2() - successfully inserts the data in table b
  • insert3() - throws the checked exception and does not insert data in table C

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

1
You are getting this error b/c Spring is trying to commit a transaction that one of your methods flagged as "rollback". Did you annotate the insert methods with Transactional too? - jeff
Actually insert1() ,insert2(),insert3() are ibatis function which are simply inserting the data in tables like sqlMapper.insert("insertAccount", account); - Lalit Goyal

1 Answers

2
votes

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.