考虑以下情况:
无状态注释类ClassOne
@Stateless
public class ClassOne {
// some injected fields
// ....
@Inject
private ClassTwo classTwo;
// ....
public void methodInClassOne() {
try {
classTwo.methodInClassTwo();
} catch(Exception e) {
// handle exception
}
}
}
无状态注释类ClassTwo
@Stateless
public class ClassTwo {
// some injected fields
// ....
@Inject
private ClassThree classThree;
// ....
public void methodInClassTwo {
try{
classThree.methodInClassThree();
} catch (Exception e) {
// handle exception
}
}
}
非注释类ClassThree
public class ClassThree {
// some injected fields
// ....
public void methodInClassThree {
// some business logic
// ....
if (conditionCheck) {
throw new RuntimeException("error message");
}
}
}
说,对于这种情况,上面的 conditionCheck 始终评估为 true 。这是今天的工作代码。 RuntimeException包装在EjbException中,并按预期捕获,处理和重新抛出,直到它到达ClassOne的catch块。但是当我创建ClassThree无状态(使用@Stateless)时,捕获的RuntimeException变为EjbTransactionRolledBackException,导致事务为Rolledback,并且尝试调用持久服务的ClassOne中的任何处理都会因此而爆炸。 我尝试过试验@TransactionAttributes:
支持,必需 - >提供相同的RollBack行为以终止交易
NOT_SUPPORTED - >甚至在条件检查之前,在JpaRepository调用上给出一个TransactionRequiredException(我假设它应该有一个带有原始非注释类的TransactionType。并且可能与ClassTwo中的事务不同 - 由于第1点。 )
REQUIRES_NEW - >这看起来像原始代码一样。
我的印象是,如果没有明确说明,那么被调用的方法/类将使用默认类型REQUIRED(显然不是这种情况,因为如第1点所述)。那么TransactionType如何在Annotated(EJB)-NonAnnotated(CDI)bean之间工作?它与两个带注释(EJB)bean之间的工作方式有何不同?我不确定我的问题是否清楚。简而言之,整个事务行为令人困惑,特别是因为ClassThree在使其无状态之前和之后的行为方式不同。
任何输入或参考更多信息都会非常有用。提前致谢
答案 0 :(得分:0)
当您将@Stateless
添加到ClassThree
时,它会隐式进行交易,并且(正如您所说)行为类型为REQUIRED
)。
每个EJB调用都通过一个名义上的边界"检查呼叫的安全凭证,并在需要时设置(新)交易(除其他外)。调用结束时,调用的结果将通过相同的边界传回。
默认情况下*,如果调用的结果是java.lang.RuntimeException
,则需要容器
这一切都发生在通过该边界的路上。
因此,methodInClassTwo
会抓住EJBTransactionRolledbackException
,EJBException
的子类。请注意,第1步会终止您的交易,而不是任何后续的异常处理。
如果methodInClassThree
标记了事务类型REQUIRES_NEW
,则在进入方法边界时始终会创建新事务。任何先前存在的交易都将暂停。抛出RuntimeException的行为如上所述,除了它是回滚的新事务。在进入边界之前处于活动状态的交易保持不变并恢复。
最后,如果methodInClassThree
标记为事务类型NOT_SUPPORTED
,则当前事务将在边界处暂停,并在呼叫完成时恢复。由于没有活动事务,因为抛出RuntimeException而没有回滚。但是你无论如何都不想要这个场景。
*您可以使用@javax.ejb.ApplicationException修改此行为。