EJB 3.0 - 嵌套事务 != 需要新事务?

29

我刚刚阅读了《精通EJB 3.0》的事务章节(第10章),现在我对于嵌套事务感到困惑。

这本书中说:

"EJB定义的事务管理器不支持嵌套事务;它只支持扁平事务。"(第278页,注)

不仅这本书这样描述,我还在其他书籍/网站上找到了类似的说法。

但如果我从一个“Required”注释的方法中调用一个“Requires New”注释的方法,那么我拥有的就是一个嵌套事务,是吗?我可以回滚内部事务或提交它,而不影响外部事务。 如果我希望终止外部事务,我抛出一个EJBException,并且整个事务将被回滚。

所以,这只是EJB 3.0规范中没有要求这种行为,还是我误解了什么?我就是弄不清楚嵌套事务和所描述的行为之间的区别。

问候 诺曼


“内部”和“外部”意味着如果我们 提交 内部,然后 回滚 外部,那么即使它已经提交,内部也会被回滚,但EJB不支持这种行为:所有事务都是彼此独立地提交和回滚的。 - DavidS
2个回答

48

RequiresNew不会创建嵌套事务,因为第一个事务在第二个事务运行时被挂起。嵌套事务的样子是这样的:

Nested transaction example
> method1 - begin tran1
  > method2 - begin tran2
    workA
  < method2 - commit tran2
< method1 - rollback tran1 (tran2 also rolled back because it's nested)

相反,RequiresNew看起来像这样:

EJB RequiresNew example
> method1 - begin tran1
  > method2 - suspend tran1, begin tran2
    workA
  < method2 - commit tran2, resume tran1
< method1 - rollback tran1 (tran2 remains committed)

1
谢谢您的回答,现在我明白了 :) 但是如果我在内部事务中使用mandatoy或required,它会像嵌套事务一样行为,尽管它属于外部事务,对吗? - NorRen
5
如果使用"mandatory"或者"required"关键字,那么容器不会为内部方法做任何事情。容器不会对事务进行"内/外"的区分,它只是让事务保持不变。 - Brett Kail
1
是的,EJB的RequiresNew与该文档中描述的"嵌套顶级事务"是相同的。EE中没有与该文档中描述的"嵌套子事务"相同的东西。 - Brett Kail
1
@MikeArgyriou 不,对于非嵌套(JTA)事务,这两个事务是完全独立的:一个事务的提交/回滚不会影响另一个事务。 - Brett Kail
2
@MikeArgyriou 不,在这种情况下,企业 bean 方法会重用客户端现有的事务,而不是开始一个新的事务(嵌套或其他)。此时,您应该打开一个新问题,而不是在这个旧答案上提问。 - Brett Kail
显示剩余3条评论

9
简单地说,"外层"事务在新事务开始之前被挂起。这两个事务的命运没有任何联系,因此在所有意图和目的上,一个事务不嵌套在另一个事务之中。
如果REQUIRES_NEW方法抛出EJBException异常,那么将回滚它所创建的新事务,而不是"外层"事务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接