Glassfish:JTA/JPA 事务未回滚

发布于 2024-12-25 02:22:24 字数 1415 浏览 1 评论 0原文

我正在使用 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 正确。

I am running Glassfish 3.1.1 with an Oracle database and have run into an issue with transactions not rolling back, but only on one specific environment so far. The same application works as expected on other machines. However, two separate Glassfish domains on the same machine are impacted.

Within the affected environment, I have similar results with both a container-managed transactions (CMT) inside an EJB that throws a RuntimeException, and a bean-managed transaction (BMT) with UserTransaction#rollback().

In both cases, the underlying issue appears to be that the JDBC connection is somehow still set with autoCommit = true even though there is a JTA transaction in progress.

My EJB/CMT test looks like this:

@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");
  }
}

and my BMT/UserTransaction test is like this:

public void rollbackUtxTest() throws Exception {
    utx.begin();

    Foo foo = new Foo();
    entityManager.persist(foo);
    entityManager.flush();

    utx.rollback();   
}

When I call either method, the INSERT INTO FOO is committed, even though the transactions were rolled back.

What am I missing - perhaps I don't have my connection pool / datasource is not set up right?

I'm using OracleConnectionPoolDataSource as the datasource class name. Is there something I need to do to ensure my database connections participate in JTA transactions?

UPDATE 1 I originally thought this was an issue with OracleConnectionPoolDataSource but it turned out it was not correlated. The same exact pool configuration works on one environment but not the other.

UPDATE 2 Clarified that this is not specifically an EJB/CMT issue, but a general JTA issue.

UPDATE 3 added info about JDBC autocommit. Confirmed that persistence.xml is correct.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风追烟花雨 2025-01-01 02:22:24

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

在 persistence.xml 中,我有

jdbc/TEST

在domain.xml中,我没有

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

相应的 - 要么丢失或拼写错误。 (我相信我最终处于这种状态,通过 UI 创建 JNDI 数据源,意识到名称错误,然后手动修复 domain.xml jdbc-resource 中的 JNDI 名称,但没有修复它resource-ref

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

It looks like this may be an issue with domain.xml, possibly a Glassfish bug.

In persistence.xml, I have

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

In domain.xml, I have

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

But no corresponding <resource-ref ref="jdbc/TEST"> - either missing or misspelled. (I believe I ended up in that state by creating the JNDI datasource through the UI, realizing the name is wrong, then fixing the JNDI name in domain.xml jdbc-resource by hand but not fixing it in resource-ref.

In this case, my injected EntityManager still works but is not participating in JTA transactions. If I fix domain.xml, it works as expected.

那小子欠揍 2025-01-01 02:22:24

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

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

You didn't wrap your Exception in an EJBException.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文