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?

Était-ce utile?

La 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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top