我使用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);
}
}
有人知道为什么在从另一个类重写方法时它不起作用吗?
答案 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)
要求新注释的要点
Container必须调用一个企业Bean方法,该方法的事务属性设置为RequiresNew,并带有一个新的事务上下文。
如果客户端在客户端未与事务上下文关联时调用企业Bean的方法,则容器AUTOMATICALLY在将方法调用委托给企业Bean业务方法之前启动新事务。 Container自动登记业务方法使用事务访问的所有资源管理器。
如果业务方法调用其他企业bean,则Container会通过调用传递事务上下文。当业务方法完成时,Container会尝试提交事务。容器在将方法结果发送到客户端之前执行提交协议。
如果客户端使用事务上下文调用,则容器在启动新事务和调用业务方法之前,使用SUSPENDS事务上下文与当前线程的关联。在业务方法和新事务完成后,容器将恢复挂起的事务关联。
<强>解决方案强>
只有在通过另一个bean的EJB引用调用方法时才会创建新事务。在同一个bean中调用create不会产生新的事务。所以你必须从另一个bean调用它。