- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在阅读 Java EE 7 的事务管理,我对嵌套事务的概念和 EJBContext#setRollbackOnly()
的功能感到困惑。
假设我有两个 session 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 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
都会这样做。通过回滚不必要的事务,您将一无所获。例如,在查询数据时,您可能会得到 NoResultException
或 NonUniqueResultException
。它们不会导致事务回滚,因为持久性上下文和数据库之间不存在不一致的风险。
您不需要指定 @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/
当我们使用MessageDrivenContext.setRollbackOnly()时,Container将回滚事务竞争,因此消息将被放回JMS队列。 该队列是否需要显式放置权限或其事务级别,以便容
我正在阅读 Java EE 7 的事务管理,我对嵌套事务的概念和 EJBContext#setRollbackOnly() 的功能感到困惑。 假设我有两个 session Bean,Bean1Impl
在我的 Web 应用程序中,我在 Apache Tomcat (TomEE)/7.0.37 服务器上使用 OpenJPA。 我的实体 User.class: @Entity @Table(name =
我在Weblogic服务器中得到以下异常,从日志来看,这绝对是weblogic内部的东西,但是,不确定weblogic正在尝试归档应用程序的哪一部分,你知道为什么会发生这种情况吗?
我有一个方法可以抛出应用程序异常,并且回滚为 true。我想知道是否必须显式调用 ejbContext.setRollbackOnly() ? 文档 here表示当异常标记为rollback=true
我有一个 java 类,它使用队列中的消息,将 HTTP 调用发送到某些 url。我已经在谷歌和 stackoverflow 上进行了一些搜索(如果我错过了任何提及该问题的消息来源,我真的很抱歉)但是
我有以下情况,我调用 BeanA 的 doSomeTask() 但如果 doSomeTask() 失败,我想将 ErrorInfo 保存到另一个表中并调用 BeanA 的 saveError(Erro
我是一名 Java 开发人员。我在本地版本的 websphere 应用程序服务器中部署了一个 Web 服务,我知道它可以在我的生产服务器上运行。 但是当我尝试使用 SOAP UI 在本地执行 Web
请帮助我了解 EJB 3.1 中的事务。我正在使用 GlassFish v3 并遇到以下情况: @Stateless @LocalBean public class BeanA { @Inje
我正在将应用程序从 Jboss 7as 移植到 Weblogic 12c。 到目前为止,我能够运行该应用程序并在数据库中创建新记录。 但是,只有在尝试更新现有记录时,我才会收到以下错误; Error
我是一名优秀的程序员,十分优秀!