Исключение Spring OpenJPA TransactionRequiredException из метода службы делегирования

#spring #transactions #tomcat6 #junit4 #openjpa

#spring #транзакции #tomcat6 #junit4 #openjpa

Вопрос:

Мы столкнулись с проблемами с управлением транзакциями Spring 3.0.5 и OpenJPA 2.0.1, и, похоже, мы не можем точно определить проблему, поэтому любая помощь приветствуется.

Архитектура может быть разбита следующим образом:

уровень сервиса

 @Autowired
private DAOInterface daoReference;
....
public void doStuff() {
     boolean test = performCheck();
}
....
private boolean performCheck() {
     return daoReference._performDAOCheck();
}
  

DAO-layer

 @PersistenceContext
private EntityManager entityManager;
.....
@Transactional
public boolean _performDAOCheck() {
     boolean result = true;
     // fetch entity manager, perform something and return boolean value
     return resu<
}
  

Этот код работает так, как должен, но нам действительно не нравится существование разграничения транзакций на уровне DAO, и мы хотели бы перенести это на уровень сервиса выше.

Однако, если мы переместим @Transactional аннотацию в метод делегирования уровня сервиса и удалим его из уровня DAO, мы получим javax.persistence.TransactionRequiredException , который указывает, что транзакция требуется, но не активна.

Вопрос в том, почему и как мы «активируем» транзакцию из метода делегирования? Имейте в виду, мы пробовали различные модификаторы распространения транзакций, но, похоже, это не дало ничего полезного (REQUIRE_NEW — единственное, что действительно применимо в этом контексте, но мы попробовали другие на всякий случай).

Стек приложения выглядит следующим образом:

  1. Spring 3.0.5
  2. Bitronix 2.1.1
  3. OpenJPA 2.0.1
  4. Tomcat 6.0.32
  5. JUnit 4.8.2 используется в качестве платформы тестирования

Ответ №1:

Для дальнейшего использования — кажется, мы решили проблему — речь идет о прокси Spring AOP, который не замечает вызовы локальных методов.

Если service-layer performCheck() перемещается в другой компонент spring bean, вводится и затем вызывается, прокси-сервер корректно генерирует новый транзакционный контекст, и все работает как по маслу.