我正在阅读 Java EE 7 的事务管理,我对嵌套事务的概念和EJBContext#setRollbackOnly()
.
假设我有两个会话 Bean,Bean1Impl
它们Bean2Impl
的签名是:
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class Bean1Impl implements Bean1 {
@Resource
private EJBContext context;
@TransactionAttribute(REQUIRED)
public void method1() {
try {
//some operations such as persist(), merge() or remove().
}catch(Throwable th){
context.setRollbackOnly();
}
}
}
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class Bean2Impl implements Bean2 {
@Resource
private EJBContext context;
@TransactionAttribute(REQUIRED)
public void method2() {
try {
//some operations such as persist(), merge() or remove().
//an exception has been thrown
}catch(Throwable th){
context.setRollbackOnly();
}
}
}
如Java EE 7 教程中所述:
51.3.1.1 必需属性
如果客户端在事务中运行并调用企业 bean 的方法,则该方法在客户端的事务中执行。如果客户端未与事务关联,则容器在运行该方法之前启动一个新事务。
Required 属性是使用容器管理的事务划分运行的所有企业 bean 方法的隐式事务属性。除非您需要覆盖另一个事务属性,否则您通常不会设置Required 属性。由于事务属性是声明性的,您可以在以后轻松更改它们。
在这种情况下,我不需要@TransactionAttribute(REQUIRED)
在方法Bean1Impl#method1()
和Bean2Impl#method2()
. 我对吗?
所以在上面的代码中,事务Bean2Impl#method2()
将在事务中运行Bean1Impl#method1()
。
我可以将其视为嵌套事务吗?
如果Exception
在方法内部抛出了Bean2Impl#method2()
一个最终会导致EJBContext.setRollbackOnly()
从catch
块中调用该方法的方法,并且正如预期的那样,它应该回滚在try
该方法的块中执行的操作。在这种情况下,交易会发生什么,以及Bean1Impl#method1()
. 也会被回滚吗?我的意思是:
如果调用EJBContext.setRollbackOnly()
fromBean2Impl#method2()
和会发生什么
Bean2Impl#method2()
Bean1Impl#method1()
在任何数据库操作(如持久化、合并或删除)之前从该方法调用。Bean2Impl#method2()
Bean1Impl#method1()
在任何数据库操作(如持久化、合并或删除)之后从该方法调用。
最后,如果方法Bean2Impl#method2()
成功执行但在成功返回后EJBContext.setRollbackOnly()
调用会发生什么?Bean1Impl#method1()
Bean2Impl#method2()