3

我用 REQUIRE_NEW 注释了一个方法,我希望它在新事务中执行。以下是代码:

public class EJBAImpl implements EJBA {
    @EJB
    private EJBB ejbb;

    public void someMethod(entity){
        ejbb.create(entity);
        //doMoreStuff
    }
}

public class BaseEJB {
    public void create(Entity entity) {
        //saveHere
    }
}

public class EJBBImpl extends BaseEJB implements EJBB {
    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void create(Entity entity) {
        super.create(entity);
    }
}

但是,当我在创建方法调用之后的行中放置一个断点(其中说 doMoreStuff)时,我的实体没有保存在数据库中。我错过了什么?我查了一下,EJBB 是一个代理。

编辑:想通了,如果方法是继承的,它就不起作用。解决方法是在EJBB中改变方法,如下:

public class EJBBImpl extends BaseEJB implements EJBB {

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void anotherNameForCreate(Entity entity) {
        super.create(entity);
    }
}

有谁知道为什么在覆盖另一个类的方法时它不起作用?

4

2 回答 2

4

@TransactionAttribute 具有特殊规则,如 ejb3.1 规范第 13.3.7.1 节所述。

如果 bean 类具有超类,则适用以下附加规则。

1) 在超类 S 上指定的事务属性适用于由 S 定义的业务方法。如果在 S 上未指定类级事务属性,则等效于在 S 上指定 TransactionAttribute(REQUIRED)。

2) 可以在由类 S 定义的业务方法 M 上指定事务属性,以便为方法 M 覆盖在类 S 上显式或隐式指定的事务属性值。

3) 如果类 S 的方法 M 覆盖由 S 的超类定义的业务方法,则 M 的事务属性由应用于类 S 的上述规则确定。

根据我的理解,您处于第三点,因此,对于 ejb 容器,实际事务属性是 REQUIRES_NEW 的@REQUIERED。

于 2013-06-29T04:22:10.387 回答
0

RequiresNew 注释要考虑的要点

  1. Container 必须调用一个企业 Bean 方法,该方法的事务属性设置为 RequiresNew,并带有一个 NEW 事务上下文。

  2. 如果客户端调用企业 Bean 的方法,而客户端未与事务上下文相关联,则容器会在将方法调用委托给企业 Bean 业务方法之前自动启动新事务。容器自动将业务方法访问的所有资源管理器与事务一起登记。

  3. 如果业务方法调用其他企业 bean,则容器通过调用传递事务上下文。当业务方法完成时,容器尝试提交事务。容器在方法结果发送到客户端之前执行提交协议。

  4. 如果客户端使用事务上下文进行调用,则容器会在开始新事务并调用业务方法之前暂停事务上下文与当前线程的关联。容器在业务方法和新事务完成后恢复挂起的事务关联。

解决方案

仅当通过 EJB 引用从另一个 bean 调用方法时才会创建新事务。在同一个 bean 中调用 create 不会产生新的事务。所以你必须从另一个 bean 调用它。

于 2013-07-01T17:08:09.537 回答