Question

I've this situation:

@Component @Transactional
public class Test{

     public void mainMetod(){
        //do some changes on db

        classA.method1();

        classA.method2();
     }  

}

@Component @Transactional
public class A{

      public method1(){
           //read some data from db that Test class wrote
      }


      public method2(){
           //read some data from db that Test class wrote 
      }
}

and app-jpa-config.xml

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <!-- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> -->
    <property name="entityManagerFactory" ref="entityManagerFactory" />
    <property name="dataSource" ref="dataSource" />
</bean>

<tx:annotation-driven />

I try to implements this behaviour:

  • I want that method1 of class A can see data written in the mainMetod of Test class
  • I'd like that if there is an exception in method1 the rollback interest only modification made by method1() and not rollback modifications made by mainMethod of Test class. I need to read updated data wrote by mainMethod of Test class
  • I'd like that if there is an exception in method2 the rollback interest only modification made by method2() and not rollback modifications made by mainMethod of Test class. I need to read updated data wrote by mainMethod of Test class

If I use default propagation, I reach the first request (can read data wrote by mainmethod) but I can't achieve the second request: rollback in method1/2 rollback entire transaction.

If I use propagation REQUIRES_NEW I achieve the second request but not the one.

I think the only method is use manual transaction using TransactionTemplate. Is correct my supposition?

Was it helpful?

Solution

nested transaction annotations is not supported in Hibernate. So the only way to solve the problem I found is using TransactionTemplate.

transactionTemplate.execute(new TransactionCallback<Void>() {

        @Override
        public Void doInTransaction(TransactionStatus status) {
}
});

All the code inside doInTransaction method is executed in transactional context. So in this way I can manage manually the exact point in which the method commit results.

Hope this can be helpful

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top