【问题标题】:Transaction not active exception - EJB Transaction State事务不活动异常 - EJB 事务状态
【发布时间】:2012-01-30 19:25:17
【问题描述】:

我遇到了负责启动事务的 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 中的默认值)。

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

非常感谢,

亚尼夫

【问题讨论】:

    标签: java transactions jboss ejb transactionmanager


    【解决方案1】:

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

    当此方法完成时,线程不再与 交易。

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

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

    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 容器启动新事务。

    【讨论】:

    • 感谢 Nicholas,为了让事情更整洁,我决定发送一条 JMS 消息,该消息将触发下一次 EJB 调用。
    猜你喜欢
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 2017-09-14
    • 2020-10-02
    • 1970-01-01
    • 2016-05-16
    • 2016-06-29
    相关资源
    最近更新 更多