java - EJB 中的嵌套事务行为

标签 java transactions ejb weblogic message-driven-bean

今天我在 EJB 中发现了一些意想不到的行为。我有默认事务属性 (REQUIRED) 的 MDB 和事务属性设置为 REQUIRES_NEW 的 SLSB。我的 MDB 调用 SLSB 并捕获 SLSB 可能引发的任何异常。当 SLSB 中发生非常糟糕的情况并且抛出 RuntimeException 的某些子类时。然后,为 SLSB 创建的新事务被标记为回滚。从我的角度来看,这是正确的行为。然后 MDB 捕获此异常并执行某些操作(例如,将消息写入日志)而不重新抛出。但 MDB 事务不知何故也被标记为回滚,这对我来说似乎很奇怪。这种行为正确吗?

更准确地说,我可以编写一些类似于实际代码的代码,从而产生这种行为:

@MessageDriven
public class A{

@EJB
private B b;

@Overried
public void onMessage(Message msg){
...
try{
b.process(msg);
} catch (Throwable t){
logger.error("Something gone wrong",t);
}
...
}

SLSB 看起来像这样:

@EJB
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class B{
public void process(Message msg){
...
}
}

有问题的任务流程如下所示:

  1. 调用了消息驱动 bean onMessage(Message)
  2. 消息驱动 Bean 成功执行一些操作,然后调用 B.process(Message) 方法。
  3. B 中发生了错误,并引发了 RuntimeException
  4. RuntimeException 被包装在 EJBException 中,并被消息驱动 bean 成功捕获。
  5. 消息驱动 bean onMessage(Message) 方法已完全执行,但其事务被标记为回滚

有人能解释一下这种行为吗? 提前致谢。

最佳答案

正如@gkuzmin所说。

EJB 3.1 规范第 13.3.7.1 节的相关部分:

如果 Bean 类具有父类(super class),则适用以下附加规则。

  • 在父类(super class) S 上指定的事务属性适用于 S 定义的业务方法。如果没有在 S 上指定类级事务属性,则相当于在 S 上指定 TransactionAttribute(REQUIRED)。

  • 可以在类 S 定义的业务方法 M 上指定事务属性,以覆盖方法 M 在类 S 上显式或隐式指定的事务属性值。

  • 如果类 S 的方法 M 覆盖由 S 的父类(super class)定义的业务方法,则 M 的事务属性由上述规则应用于类 S 确定。 p>

注意粗体部分。它不是您所期望的 S 父类(super class)的业务方法。

关于java - EJB 中的嵌套事务行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11748749/

相关文章:

java - 创建动态增长的数组所需的工作单元

java - 在 kotlin 中找不到类?

java - spring中物理事务和逻辑事务的区别

java - PersistenceUnitInfo [appName] 有事务类型 JTA,但没有定义 jtaDataSource

java - 拆分 Bean 还是在一个项目中制作所有 Bean?

java - 将 int 转换为 byte 在 Netbeans 和 JCreator 中给出不同的结果

java - ScrollView 中的可扩展 ListView 不显示所有标题标题

php - 如何处理可能有重复条目的 PDO 事务

java - 将 EJB jar 中的 POJO 类注入(inject)到不同 EJB jar 中的 EJB

java - 带有 @OSGiService 的 EJB 名称