首页 文章

Glassfish:JTA / JPA交易没有回滚

提问于
浏览
1

我正在使用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 回答

  • 0

    看起来这可能是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,它会按预期工作 .

  • 3

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

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

相关问题