Jakarta ee 跨各种bean类型的JavaEE事务类型

Jakarta 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();

考虑以下场景:

无状态注释类ClassOne

@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:

  • SUPPORTS,REQUIRED->提供相同的回滚行为终止事务

  • NOT_SUPPORTED->即使在条件检查之前,在JpaRepository调用上也会给出TransactionRequiredException(我假设应该有一个TransactionType和原始的非注释类。并且可能与第二类中的事务不同-由于第1点)

  • 需要_NEW->,其行为似乎与原始代码的行为相同

  • 我的印象是,如果没有明确说明,那么被调用的方法/类将使用所需的默认类型(显然不是这样,因为如第1点所述)。那么TransactionType如何在带注释(EJB)-非注释(CDI)bean之间工作呢?它与两个带注释(EJB)bean之间的工作方式不同吗?我不确定我的问题是否清楚。简言之,整个事务行为令人困惑,特别是因为它在使Class3成为无状态之前和之后的行为不同


    任何关于这方面的信息的输入或参考都会非常有用。提前感谢

    当您将
    @无状态
    添加到
    第三类
    时,它将成为隐式事务性的,并且(如您所说)以
    必需的事务类型运行

    每个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中处理事务的默认方式有很大区别。默认情况下,后者不参与/影响交易。