【发布时间】:2018-05-09 13:30:00
【问题描述】:
考虑以下场景:
无状态注释类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,导致事务被回滚,并且 ClassOne 中任何尝试调用持久服务的处理都因此而崩溃。 我尝试使用 @TransactionAttributes 进行试验:
支持,必需 -> 提供相同的回滚行为终止事务
NOT_SUPPORTED -> 甚至在条件检查之前,在 JpaRepository 调用上给出一个 TransactionRequiredException (我假设应该有一个带有原始非注释类的 TransactionType。而且可能不是同一个 Transaction就像在 ClassTwo 中一样 - 由于第 1 点。)
REQUIRES_NEW -> 似乎与原始代码的行为相同。
我的印象是,如果没有明确说明,那么调用的方法/类将使用默认类型 REQUIRED(显然不是这种情况,因为如第 1 点所述)。那么 TransactionType 在 Annotated(EJB)-NonAnnotated(CDI) bean 之间是如何工作的呢?它与两个 Annotated(EJB) bean 之间的工作方式不同吗?我不确定我的问题是否清楚。简而言之,整个 Transaction 行为令人困惑,尤其是因为 ClassThree 在使其成为无状态之前和之后的行为方式不同。
对此的更多信息的任何输入或参考都会非常有帮助。提前致谢
【问题讨论】:
-
我不认为它是带注释的 vs 未注释的,而是(就像你的标题暗示的那样,以及添加的 cdi 标记)EJB 与 CDI bean
-
是的,它是 EJB(前两个类)与 CDI(第三类)。对困惑感到抱歉。我有兴趣了解事务在两个 EJB bean 之间(我认为这很简单)以及在 EJB 和 CDI bean 之间(令人困惑的部分 - 如上所述,行为在我做出后立即改变) CDI bean 也是 EJB)
-
你读过stackoverflow.com/questions/17838221/… 吗?在 EJB 与 CDI 中处理事务的默认方式之间存在重大差异。后者默认不参与/影响交易。
标签: jakarta-ee ejb cdi stateless-session-bean session-bean