gpt4 book ai didi

java - 嵌套事务和 EJBContext 的 setRollbackOnly()

转载 作者:搜寻专家 更新时间:2023-11-01 01:43:26 24 4
gpt4 key购买 nike

我正在阅读 Java EE 7 的事务管理,我对嵌套事务的概念和 EJBContext#setRollbackOnly() 的功能感到困惑。

假设我有两个 session Bean,Bean1ImplBean2Impl,它们的签名是:

@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 Tutorial 中所述:

51.3.1.1 Required Attribute

If the client is running within a transaction and invokes the enterprise bean's method, the method executes within the client's transaction. If the client is not associated with a transaction, the container starts a new transaction before running the method.

The Required attribute is the implicit transaction attribute for all enterprise bean methods running with container-managed transaction demarcation. You typically do not set the Required attribute unless you need to override another transaction attribute. Because transaction attributes are declarative, you can easily change them later.

在这种情况下,我不需要在方法 Bean1Impl#method1()Bean2Impl#method2( )。我说得对吗?

所以在上面的代码中,Bean2Impl#method2() 的事务将在 Bean1Impl#method1() 的事务中运行。

我可以将其视为嵌套事务吗?

如果在方法 Bean2Impl#method2() 中抛出了一个 Exception,最终将导致调用方法 EJBContext.setRollbackOnly( ) 来自 catch block ,正如预期的那样,它应该回滚在此方法的 try block 中执行的操作。在这种情况下,事务以及 Bean1Impl#method1() 会发生什么。它也会回滚吗?我的意思是:

如果 Bean2Impl#method2()

调用了 EJBContext.setRollbackOnly() 会发生什么
  • Bean2Impl#method2() 在任何数据库操作(如保留、合并或删除)之前从方法 Bean1Impl#method1() 调用。
  • Bean2Impl#method2() 在任何数据库操作(如保留、合并或删除)之后从方法 Bean1Impl#method1() 调用。

最后,如果方法 Bean2Impl#method2() 成功执行但 EJBContext.setRollbackOnly() 是从 Bean1Impl#method1() 调用的,会发生什么 Bean2Impl#method2() 成功返回后?

最佳答案

添加到@Philippe Marshall 的正确答案和您的评论 - REQUIRES_NEW 将创建一个独立于第一个事务的新事务。它们不是嵌套的。第一个事务暂停,而第二个事务处于 Activity 状态。一旦第二个事务提交,第一个事务将恢复。

您不必手动setRollbackOnly()。如果需要,大多数 PersistenceException 都会这样做。通过回滚不必要的事务,您将一无所获。例如,在查询数据时,您可能会得到 NoResultExceptionNonUniqueResultException。它们不会导致事务回滚,因为持久性上下文和数据库之间不存在不一致的风险。

您不需要指定 @TransactionAttribute(REQUIRED)@TransactionManagement(TransactionManagementType.CONTAINER) - 两者都是默认设置。

编辑:回答您进一步的问题:

我假设 @TransactionAttribute(REQUIRES_NEW)method2 上,因此有两个单独的事务。

如果在method2中出现Exception导致事务回滚,则method1中的事务不会回滚异常被捕获。如果未捕获到 Exception,则两个事务都将回滚。

在事务上设置回滚标志时,它发生在数据库操作之前还是之后并不重要,因为整个事务都会回滚。

一旦 method2 返回,它的事务就被提交。之后从method1 回滚或提交事务对第一个事务的结果没有影响。

一般性建议 - 不要捕获 Throwable - 它过于宽泛,您可能会吞下您宁愿传播到表面的异常。

关于java - 嵌套事务和 EJBContext 的 setRollbackOnly(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20823798/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com