2

我遇到了负责启动事务的 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()我得到一个异常,最终告诉我事务不活跃。

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

那为什么我会得到“交易不活跃”?

非常感谢,

亚尼夫

4

1 回答 1

3

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

当此方法完成时,线程不再与事务关联。

There's two ways to deal with this (and I am outlining them in a very raw manner which you may want to refine a bit).

Option 1: Issue a rollback or commit against the transaction manager (in a try block because it will fail).

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

Option 2: Start a new transaction, which will satisfy the REQUIRED attribute of your EJB by pre-starting a transaction, but you need to stick around and manage it which gets sticky.

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

Option 3: The cleanest option may be to mark the EJB method as REQUIRES_NEW as this will force the EJB container to start a new transaction.

于 2012-02-01T14:30:33.360 回答