Проблема с менеджером транзакций множественного гибернации

#transactions #annotations #spring-3 #sessionfactory #hibernate-4.x

#транзакции #примечания #весна-3 #sessionfactory #гибернация-4.x

Вопрос:

Я работаю с Spring 3.2.5.Release и Hibernate 4.2.7.Final. Я развертываю свой ear на сервере Websphere 7. У меня есть два файла контекста приложения, и каждый из них имеет свой собственный SessionFactory типа

    <bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">....</bean>


   <bean id="sessionFactory1"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" lazy-init="true">... </bean> 
  

Проблема связана с несколькими HibernateTransactionManager. Я определяю двух менеджеров транзакций как

    <bean id="transactionManager"
     class="org.springframework.orm.hibernate4.HibernateTransactionManager">
     <property name="sessionFactory" ref="sessionFactory" />
     <qualifier value="transactionManager"/>
   </bean>
  

и

    <bean id="txManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory1" />
    <qualifier value="txManager"/>
</bean>
  

В одном из контекстных файлов я упоминал об этом

     <tx:annotation-driven/>
<bean
    class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
  

Однако во время выполнения этого кода,

     loggingManager.persistLog(loadLog); // using txManager
    .....
    persistenceService.persist(dataEntity);  // using transactionManager
  

Я получаю приведенное ниже исключение

     org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
  

Пожалуйста, обратите внимание, что первая транзакция прошла успешно. Я вижу идентификатор, сгенерированный для loadLog. Я аннотировал свой уровень обслуживания с

     @Transactional(value="txManager") // with respective transaction manager
  

И мой уровень DAO с

     @Transactional(propagation = Propagation.MANDATORY) 
  

Можно ли что-нибудь сделать, чтобы включить оба диспетчера транзакций?

Ответ №1:

Служба использует txManager

 @Transactional(value="txManager") 
  

Эта служба вызывает репозиторий или dao, она также должна принадлежать или выполняться в рамках транзакции службы. Вы должны выполнить следующее:

 @Transactional(value="txManager" propagation = Propagation.MANDATORY) 
  

Почему происходит распространение.ОБЯЗАТЕЛЬНО? Почему бы не распространение.ТРЕБУЕТСЯ? Или просто только

 @Transactional(value="txManager") 
  

С момента распространения.По умолчанию используется значение REQUIRED.

Кстати, рассмотрите возможность использования только @Transactional , если ваши @Transactional services будут работать либо с txManager, либо с TransactionManager

Комментарии:

1. Это работает! Я добавил квалификатор transaction manager на уровень DAO, и это работает как шарм. Распространение. Требуется, чтобы уровень DAO не вызывался в обход уровня обслуживания. На самом деле это хорошая практика.

2. Интересно, у меня всегда есть мои методы DAO с «Обязательными», только мои сервисы для сложных вариантов использования будут «REQUIRES_NEW», обычно они тоже «ОБЯЗАТЕЛЬНЫ». Конечно, каждое требование отличается.