1

我正在使用 Oracle 数据库运行 Glassfish 3.1.1,并且遇到了事务不回滚的问题,但到目前为止仅在一个特定环境中。相同的应用程序在其他机器上按预期工作。但是,同一台机器上的两个单独的 Glassfish 域会受到影响。

在受影响的环境中,我在 EJB 中的容器管理事务 (CMT) 和抛出 RuntimeException 的容器管理事务 (CMT) 和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 问题。

UPDATE 3添加了有关 JDBC 自动提交的信息。确认persistence.xml 是正确的。

4

2 回答 2

3

看起来这可能是 domain.xml 的问题,可能是 Glassfish 错误。

在persistence.xml中,我有

<jta-data-source>jdbc/TEST</jta-data-source>.

在 domain.xml 中,我有

<jdbc-resource pool-name="TEST_POOL" description="" jndi-name="jdbc/TEST"></jdbc-resource>

但没有相应<resource-ref ref="jdbc/TEST">的 - 丢失或拼写错误。(我相信我最终通过 UI 创建 JNDI 数据源,意识到名称错误,然后jdbc-resource手动修复 domain.xml 中的 JNDI 名称但没有在resource-ref.

在这种情况下,我的注入EntityManager仍然有效,但没有参与 JTA 事务。如果我修复 domain.xml,它会按预期工作。

于 2012-01-10T19:33:16.480 回答
0

您没有将异常包装在 EJBException 中。

请参阅http://docs.oracle.com/javaee/6/tutorial/doc/bnbpj.html

于 2012-02-04T03:09:39.667 回答