我正在使用Oracle数据库运行Glassfish 3.1.1并且遇到了一个问题,即事务没有回滚,但到目前为止只在一个特定的环境中运行 . 相同的应用程序在其他计算机上按预期工作 . 但是,同一台计算机上的两个单独的Glassfish域受到影响 .
在受影响的环境中,我在EJB中抛出RuntimeException的容器管理事务(CMT)和使用 UserTransaction#rollback()
的bean管理事务(BMT)都有类似的结果 .
在这两种情况下,基本问题似乎是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事务,我需要做些什么吗?
UPDATE 1 我最初认为这是 OracleConnectionPoolDataSource
的一个问题,但事实证明它没有相关性 . 相同的池配置适用于一个环境,但不适用于另一个环境 .
UPDATE 2 澄清这不是特定的EJB / CMT问题,而是一般的JTA问题 .
UPDATE 3 添加了有关JDBC自动提交的信息 . 确认persistence.xml是正确的 .
2 回答
看起来这可能是domain.xml的问题,可能是Glassfish错误 .
在persistence.xml中,我有
<jta-data-source>jdbc/TEST</jta-data-source>
.在domain.xml中,我有
但没有相应的
<resource-ref ref="jdbc/TEST">
- 要么丢失要么拼错了 . (我相信我最后通过UI创建JNDI数据源,意识到名称错误,然后手动修复域名jdbc-resource
中的JNDI名称,但没有在resource-ref
中修复它 .在这种情况下,我注入
EntityManager
仍然有效,但没有参与JTA事务 . 如果我修复domain.xml,它会按预期工作 .您没有在EJBException中包装您的Exception .
见http://docs.oracle.com/javaee/6/tutorial/doc/bnbpj.html