java - 事务未激活异常 - EJB 事务状态

标签 java transactions jboss ejb transactionmanager

我在负责启动事务的 EJB 组件方面遇到问题。 我使用的是Jboss 5.01。

基本上我想在提交特定事务后执行给定的代码。具体代码还涉及调用 EJB 组件来生成自己的事务。

为了确保我的代码在提交上一个事务后执行,我注册了一个 同步组件变成事务组件:

Transaction tx = transactionManager.getTransaction();
tx.registerSynchronization(new CallbackSynchronization());

Synchronizaton实现基本上执行以下操作:

class CallbackSynchronization implements Synchnronization {

    private AccountService service;  // This is a Stateless session bean

    public CallbackSynchronization(AccountService service) {
        this.service   = service;
    }

    public afterCompletion(int status) {
        if(Status.STATUS_COMMITTED == status) {
            service.deleteAccounts();
        }
    }
}

问题是当我调用service.deleteAccounts()时我收到一个异常,最终告诉我交易不活跃。

这就是让我困惑的地方。其方法标记为 @TransactionAttribute(TransactionAttributeType.REQUIRED) 的 EJB如果事务不活动,将创建一个新事务(REQUIRED 是 JBOSS 中的默认值)。

为什么我会收到“交易未激活”?

非常感谢,

亚尼夫

最佳答案

问题是您启动的原始事务仍然与该线程关联(即使它处于 COMMITTED 状态)。使用 Transaction 之间的显着差异之一和 TransactionManager是后者的commit()rollback()方法将取消事务与线程的关联。引用这两种方法的 javadoc:

When this method completes, the thread is no longer associated with a transaction.

有两种方法可以解决这个问题(我以一种非常原始的方式概述了它们,您可能需要稍微改进一下)。

选项 1:针对事务管理器发出回滚或提交(在 try block 中,因为它会失败)。

public afterCompletion(int status) {
  if(Status.STATUS_COMMITTED == status) {
    try { transactionManager.rollback(); } catch (Throwable t) {}
    service.deleteAccounts();
  }
}

选项 2:启动一个新事务,这将通过预启动事务来满足 EJB 的 REQUIRED 属性,但您需要坚持下去并管理它,这会变得粘性。

public afterCompletion(int status) {
  if(Status.STATUS_COMMITTED == status) {
    try { 
      transactionManager.begin();
      service.deleteAccounts();
      transactionManager.commit();
    } catch (Exception e) {
        // ... handle exception here
    }
  }
}

选项 3:最干净的选项可能是将 EJB 方法标记为 REQUIRES_NEW,因为这将强制 EJB 容器启动新事务。

关于java - 事务未激活异常 - EJB 事务状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9069518/

相关文章:

java - JBoss NoClassDefFoundError 中的 docx4j

java - 如何使java形状以圆形动画?

java - VSCode 中的自动 ActiveJDBC 检测

Java Swing Gridbag 面板不会 colspan

c# - 在 Entity Framework 中使用 2 个 DbContext 回滚事务。使用 TransactionScope 还是 TransactionBegin?

MySQL,如果不存在则插入行

hibernate - 如何配置 Spring Boot 应用程序以使用 aspectj 事务?

jboss - resteasy-cdi - 出现 "Duplicate context initialization parameter resteasy.injector.factory"错误

java - 简单的 RESTtEasy 示例不起作用

java - 在 JBoss SOA 上发布自定义 Web 服务