EJB Transaction REQUIRES_NEW

时间:2013-06-28 16:22:16

标签: java-ee transactions ejb ejb-3.0

我使用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);
    }
}

Howerver,当我在create方法调用之后在行中放置一个断点(其中说doMoreStuff)时,我的实体没有保存在DB中。我错过了什么?我检查过,EJBB是代理。

编辑:想象一下,如果方法是继承的,它就不起作用。解决方案是在EJBB中更改方法,如下所示:

public class EJBBImpl extends BaseEJB implements EJBB {

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

有人知道为什么在从另一个类重写方法时它不起作用吗?

2 个答案:

答案 0 :(得分:3)

@TransactionAttribute有特殊规则,ejb3.1规范在13.3.7.1节中描述。​​

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

  

1)在超类S上指定的事务属性适用于   由S.定义的业务方法如果是类级事务属性   在S上没有指定,它相当于规范   S上的TransactionAttribute(REQUIRED)。

     

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

     

3)如果类S的方法M覆盖由a定义的业务方法   S的超类由M的事务属性决定   以上适用于S类的规则。

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

答案 1 :(得分:0)

要求新注释的要点

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

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

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

  4. 如果客户端使用事务上下文调用,则容器在启动新事务和调用业务方法之前,使用SUSPENDS事务上下文与当前线程的关联。在业务方法和新事务完成后,容器将恢复挂起的事务关联。

  5. <强>解决方案

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