Проблема с диспетчером транзакций с несколькими гибернациями

Я работаю с Spring 3.2.5.Release и Hibernate 4.2.7.Final. Я развертываю свое ухо на сервере 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) 

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


person Kabira Speaking    schedule 04.07.2014    source источник


Ответы (1)


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

@Transactional(value="txManager") 

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

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

Почему Propagation.MANDATORY? Почему бы не использовать Propagation.REQUIRED? Или просто только

@Transactional(value="txManager") 

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

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

person Manuel Jordan    schedule 04.07.2014
comment
Это работает! Я добавил квалификатор диспетчера транзакций на уровень DAO, и он работает как шарм. Propagation.Required останавливает вызов уровня DAO в обход уровня обслуживания. На самом деле это хорошая практика. - person Kabira Speaking; 04.07.2014
comment
Интересно, у меня всегда есть методы DAO с Required, только мои сервисы для сложных случаев использования будут REQUIRES_NEW, обычно они тоже REQUIRED. Конечно, каждое требование отличается. - person Manuel Jordan; 05.07.2014