Вложенная транзакция Spring с Hibernate

у меня такая ситуация:

@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 
      }
}

и приложение-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 />

Я пытаюсь реализовать это поведение:

  • Я хочу, чтобы метод1 класса А мог видеть данные, записанные в классе mainMetod класса Test.
  • Я бы хотел, чтобы, если в методе1 есть исключение, откат интересовался только модификацией, сделанной методом 1(), а не изменениями отката, сделанными mainMethod класса Test. Мне нужно прочитать обновленные данные, записанные mainMethod класса Test
  • Я бы хотел, чтобы, если в методе 2 есть исключение, откат интересовался только модификацией, сделанной методом 2(), а не изменениями отката, сделанными mainMethod класса Test. Мне нужно прочитать обновленные данные, записанные mainMethod класса Test

Если я использую распространение по умолчанию, я получаю первый запрос (могу прочитать данные, записанные основным методом), но я не могу выполнить второй запрос: откат в методе 1/2 откатывает всю транзакцию.

Если я использую распространение REQUIRES_NEW, я получаю второй запрос, но не тот.

Я думаю, что единственный метод - использовать ручную транзакцию с использованием TransactionTemplate. Верно ли мое предположение?


person drenda    schedule 18.10.2013    source источник


Ответы (1)


вложенные аннотации транзакций не поддерживаются в Hibernate. Таким образом, единственный способ решить проблему, которую я обнаружил, — это использовать TransactionTemplate.

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

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

Весь код внутри метода doInTransaction выполняется в транзакционном контексте. Таким образом, я могу вручную управлять точной точкой, в которой происходит фиксация метода.

Надеюсь, это может быть полезно

person drenda    schedule 07.01.2014