#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», обычно они тоже «ОБЯЗАТЕЛЬНЫ». Конечно, каждое требование отличается.