#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 — единственное, что действительно применимо в этом контексте, но мы попробовали другие на всякий случай).
Стек приложения выглядит следующим образом:
- Spring 3.0.5
- Bitronix 2.1.1
- OpenJPA 2.0.1
- Tomcat 6.0.32
- JUnit 4.8.2 используется в качестве платформы тестирования
Ответ №1:
Для дальнейшего использования — кажется, мы решили проблему — речь идет о прокси Spring AOP, который не замечает вызовы локальных методов.
Если service-layer performCheck()
перемещается в другой компонент spring bean, вводится и затем вызывается, прокси-сервер корректно генерирует новый транзакционный контекст, и все работает как по маслу.