Glassfish: транзакция JTA/JPA не откатывается
Я использую Glassfish 3.1.1 с базой данных Oracle, и у меня возникла проблема с транзакциями, которые не откатываются, а пока только в одной конкретной среде. То же приложение работает, как и ожидалось, на других машинах. Однако это влияет на два отдельных домена Glassfish на одном компьютере.
В затронутой среде у меня есть похожие результаты как с транзакциями, управляемыми контейнером (CMT) внутри EJB, который генерирует исключение RuntimeException, так и с транзакцией, управляемой бином (BMT) с UserTransaction#rollback()
,
В обоих случаях основная проблема заключается в том, что соединение JDBC каким-то образом все еще установлено с помощью autoCommit = true, даже если выполняется транзакция JTA.
Мой тест EJB/CMT выглядит так:
@Named
@Stateless
public class TransactionTest {
@PersistenceContext
EntityManager entityManager;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void rollbackTest() {
Foo foo = new Foo();
entityManager.persist(foo);
entityManager.flush();
throw new RuntimeException("should be rolled back");
}
}
и мой тест BMT/UserTransaction выглядит так:
public void rollbackUtxTest() throws Exception {
utx.begin();
Foo foo = new Foo();
entityManager.persist(foo);
entityManager.flush();
utx.rollback();
}
Когда я вызываю любой метод, INSERT INTO FOO
зафиксировано, даже если транзакции были отменены.
Чего мне не хватает - возможно, у меня нет пула соединений / источник данных не настроен правильно?
Я использую OracleConnectionPoolDataSource в качестве имени класса источника данных. Что мне нужно сделать, чтобы мои подключения к базе данных участвовали в транзакциях JTA?
ОБНОВЛЕНИЕ 1 Я первоначально думал, что это была проблема с OracleConnectionPoolDataSource
но оказалось, что это не было связано. Та же самая конфигурация пула работает в одной среде, но не в другой.
ОБНОВЛЕНИЕ 2 Уточнил, что это не проблема EJB/CMT, а общая проблема JTA.
ОБНОВЛЕНИЕ 3 добавил информацию об автокоммите JDBC. Подтвердил, что файл persistence.xml правильный.
2 ответа
Похоже, что это может быть проблема с domain.xml, возможно, ошибка Glassfish.
В persistence.xml у меня есть
<jta-data-source>jdbc/TEST</jta-data-source>
,
В домене.xml у меня есть
<jdbc-resource pool-name="TEST_POOL" description="" jndi-name="jdbc/TEST"></jdbc-resource>
Но не соответствует <resource-ref ref="jdbc/TEST">
- либо отсутствует, либо написано с ошибкой. (Я полагаю, что оказался в этом состоянии, создав источник данных JNDI через пользовательский интерфейс, осознав, что имя неверно, а затем исправив имя JNDI в файле domain.xml. jdbc-resource
вручную, но не исправляя resource-ref
,
В этом случае мой вводят EntityManager
все еще работает, но не участвует в транзакциях JTA. Если я исправлю domain.xml, он будет работать как положено.
Вы не включили свое исключение в исключение EJBException.