Glassfish:JTA / JPA交易没有回滚

时间:2012-01-06 17:31:30

标签: jpa ejb glassfish-3 jta bean-managed-transactions

我正在使用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事务吗?

更新1 我原本认为这是OracleConnectionPoolDataSource的一个问题,但事实证明它没有相关性。相同的池配置适用于一个环境,但不适用于另一个环境。

更新2 澄清这不是特定的EJB / CMT问题,而是一般的JTA问题。

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

2 个答案:

答案 0 :(得分: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中的JNDI名称,但没有在resource-ref中修复它。

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

答案 1 :(得分:0)

您没有在EJBException中包装您的Exception。

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