Java EJB中的嵌套事务行为

Java EJB中的嵌套事务行为,java,transactions,ejb,weblogic,message-driven-bean,Java,Transactions,Ejb,Weblogic,Message Driven Bean,今天我在EJB中发现了一些意想不到的行为。我得到了具有默认事务属性(REQUIRED)的MDB和事务属性设置为REQUIRES\u NEW的SLSB。我的MDB调用SLSB并捕获SLSB可以抛出的任何异常。当SLSB中发生真正糟糕的事情并且抛出了RuntimeException的某个子类时。然后,为SLSB创建的新事务被标记为回滚。在我看来,这是一种正确的行为。然后MDB捕获此异常并使用我们的rethrow执行一些操作(例如,将消息写入日志)。但是MDB事务不知何故也被标记为回滚,这对我来说似乎

今天我在EJB中发现了一些意想不到的行为。我得到了具有默认事务属性(
REQUIRED
)的MDB和事务属性设置为
REQUIRES\u NEW
的SLSB。我的MDB调用SLSB并捕获SLSB可以抛出的任何异常。当SLSB中发生真正糟糕的事情并且抛出了
RuntimeException
的某个子类时。然后,为SLSB创建的新事务被标记为回滚。在我看来,这是一种正确的行为。然后MDB捕获此异常并使用我们的rethrow执行一些操作(例如,将消息写入日志)。但是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){
...
}
}
有问题的任务流如下所示:

@EJB
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class B{
public void process(Message msg){
...
}
}
  • 调用了消息驱动bean
    onMessage(Message)
  • 消息驱动bean成功执行一些操作,然后调用
    B.process(Message)
    方法
  • B
    中发生错误,引发了
    RuntimeException
  • RuntimeException
    被包装在
    EJBException
    中,并被消息驱动bean成功捕获
  • 消息驱动bean
    onMessage(Message)
    方法已完全执行,但其事务已标记为回滚
  • 有人能解释这种行为吗?
    提前感谢。

    已找到此问题的解决方案。实际上,
    TransactionAttribute
    注释被放置在
    B
    bean的抽象超类上,并被忽略。WebLogic server中的EJB运行时环境忽略
    B
    超类中的注释,并使用默认的
    REQUIRED
    属性。如果您遇到同样的问题,我建议您阅读EJB3.1规范中的13.3.7.1节(您可以下载)。

    如@gkuzmin所述


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

    如果bean类有超类,则应用以下附加规则

    • 在超类S上指定的事务属性适用于由S定义的业务方法。如果未在S上指定类级事务属性,则相当于在S上指定TransactionAttribute(必需)

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

    • 如果类S的方法M覆盖了由超类S定义的业务方法,则M的事务属性由应用于类S的上述规则决定


    请注意粗体部分。它不是您所期望的S超类的业务方法。

    您使用的是什么appserver/版本?此链接表明您的评估是正确的,因为您的代码应该可以工作:。您还可以尝试将这两个bean的一个最小示例放在一起—首先验证在删除所有其他“内容”的情况下是否看到预期的行为,然后给其他人一些可以在其他平台上玩的东西。但这里没有承诺。我使用WebLogic12c服务器。目前我无法提供任何可以组装和部署的示例,但我将在未来10-20小时内提供。也许我会在尝试提供示例时发现问题。:)我冒昧地删除了EJB3标签并添加了weblogic;这可能比另一个更相关。如果你把它换回来,你不会冒犯我的。它并不是真的没用;添加您自己的答案并接受它。这可能对其他人很有帮助。EJB 3.1规范第13.3.7.1节中的相关部分: