Jakarta ee 跨各种bean类型的JavaEE事务类型
考虑以下场景: 无状态注释类ClassOneJakarta ee 跨各种bean类型的JavaEE事务类型,jakarta-ee,ejb,cdi,stateless-session-bean,session-bean,Jakarta Ee,Ejb,Cdi,Stateless Session Bean,Session Bean,考虑以下场景: 无状态注释类ClassOne @Stateless public class ClassOne { // some injected fields // .... @Inject private ClassTwo classTwo; // .... public void methodInClassOne() { try { classTwo.methodInClassTwo();
@Stateless
public class ClassOne {
// some injected fields
// ....
@Inject
private ClassTwo classTwo;
// ....
public void methodInClassOne() {
try {
classTwo.methodInClassTwo();
} catch(Exception e) {
// handle exception
}
}
}
无状态注释类2
@Stateless
public class ClassTwo {
// some injected fields
// ....
@Inject
private ClassThree classThree;
// ....
public void methodInClassTwo {
try{
classThree.methodInClassThree();
} catch (Exception e) {
// handle exception
}
}
}
非注释类3
public class ClassThree {
// some injected fields
// ....
public void methodInClassThree {
// some business logic
// ....
if (conditionCheck) {
throw new RuntimeException("error message");
}
}
}
例如,对于这种情况,上述条件检查总是计算为true。这是截至今天的工作代码。RuntimeException被包装在一个EjbException中,并按预期捕获、处理和重试,直到它到达ClassOne的catch块。但是,当我将ClassThree设置为无状态(带有@Stateless)时,捕获的RuntimeException会变成一个EjbTransactionRolledBackException,导致事务回滚,ClassOne中尝试调用持久化服务的任何处理都会因此而崩溃。
我尝试了@TransactionAttribute:
任何关于这方面的信息的输入或参考都会非常有用。提前感谢当您将
@无状态
添加到第三类
时,它将成为隐式事务性的,并且(如您所说)以必需的事务类型运行
每个EJB调用都会通过一个概念上的“边界”,在这里检查调用的安全凭证,并在需要时设置(新的)事务(除其他事项外)。调用的结果在调用完成时通过同一边界传回
默认情况下*,如果调用的结果是java.lang.RuntimeException
,则要求容器
将当前事务标记为回滚
将RuntimeException包装到EJBException中
重新显示新的EJBException
这一切都发生在通过边界返回的路上
因此,methodInClassTwo
捕获一个EJBTransactionRolledbackException
,它是EJBException
的子类。请注意,终止事务的是步骤1,而不是任何后续异常处理
如果将methodInClassThree
标记为交易类型REQUIRES\u NEW
,则始终在进入方法边界时创建新交易。任何以前存在的交易都将暂停。抛出RuntimeException的行为如上所述,只是回滚的是新事务。在进入边界之前处于活动状态的事务将保持不变并恢复
最后,如果methodInClassThree
被标记为不受支持的事务类型,则当前事务在边界处暂停,并在调用完成时恢复。由于没有活动事务,因此不会由于引发RuntimeException而回滚。但无论如何,你都不希望出现这种情况
&天冬氨酸;您可以使用来修改此行为。我不认为它是带注释的还是不带注释的,而是(就像您的标题和添加的cdi标记一样)EJB vs cdi Beans是的,它是EJB(前两个类)vs cdi(第三个类)。很抱歉给你带来了困惑。我很想知道当事务在两个EJB bean之间(我认为这是非常直接的)和在EJB和CDIBean之间(令人困惑的部分——如上所述,当我将CDIBean也变成EJB时,行为就改变了)时,事务是如何不同的。你读过了吗?EJB中处理事务的默认方式与CDI中处理事务的默认方式有很大区别。默认情况下,后者不参与/影响交易。