22

在以下设置中,方法 B 是否在(新)事务中运行?

一个 EJB,有两种方法,方法 A 和方法 B

public class MyEJB implements SessionBean
    public void methodA() {
       doImportantStuff();
       methodB();
       doMoreImportantStuff();
    }

    public void methodB() {
       doDatabaseThing();
    }
}

EJB 是容器管理的,methodB 在 requires_new 事务中,method A 在 required 事务中。因此:

<container-transaction id="MethodTransaction_1178709616940">
  <method id="MethodElement_1178709616955">
    <ejb-name>MyName</ejb-name>
    <method-name>*</method-name>
  <trans-attribute>Required</trans-attribute>
  </method>
  <method id="MethodElement_1178709616971">
    <ejb-name>MyName</ejb-name>
    <method-name>methodB</method-name>
  </method>
  <trans-attribute>RequiresNew</trans-attribute>
</container-transaction>

现在让另一个 EJB 使用 EJB 方法调用来调用 methodA。methodA 现在在事务中运行。从 methodA 对 methodB 的后续调用会在同一个事务中运行,还是在新事务中运行?(请注意,这里是实际代码。没有对方法 B 的显式 ejb 调用)

4

3 回答 3

39

您的调用methodB()是对方法的普通调用,不会被 EJB 容器拦截;在运行时,EJB 容器将注入一个代理而不是您的类的实例,这是它在调用您的方法之前拦截调用并设置环境的方式。如果你使用this你直接调用一个方法,而不是通过代理。因此,这两种方法都将使用相同的事务,而不管 ejb-jar.xml 中为通过 EJB 接口的调用定义了什么。

于 2009-01-09T10:09:51.643 回答
23

注入 SessionContext,并要求它提供您的代理实例:

@Stateless
public class UserFacade implements UserFacadeLocal {
    @Resource
    private SessionContext context;

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    private void create(User user) {
        System.out.println("Users Count: "+count()); //invocation#1
        System.out.println("Users Count Through Context: "+context.getBusinessObject(UserFacadeLocal.class).count()); //invocation#2
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.NEVER)
    public int count() {
        return ((Long) q.getSingleResult()).intValue();
    }
}

在 'invocation#1' 这是一个本地调用,不通过代理,它将返回计数

在'invocation#2'中,这是通过代理的调用,因此您将其注释为不支持事务-现在由 create(user) 方法打开-,此调用将引发事务异常:

javax.ejb.EJBException:无法在全局事务中调用 EJB

于 2012-09-08T12:11:38.750 回答
4

他们将使用相同的交易。

如果我没记错的话,事务是由容器“在”该方法“完成”后调用和提交之前启动的。

由于“a”调用“b”,“b”将使用相同的事务。

:S

我想你能做的最好的事情就是测试它来验证它!:)

于 2009-01-09T09:22:03.313 回答