EJB3 事务回滚

Posted

技术标签:

【中文标题】EJB3 事务回滚【英文标题】:EJB3 transaction rollback 【发布时间】:2011-01-22 13:51:44 【问题描述】:

我在 EJB3 无状态会话 bean 中使用 CMT。我还创建了自己的异常,带有注释“@ApplicationException (rollback=true)”。

    当我想回滚事务时,是否必须使用“context.setRollbackOnly()”?

    我可以通过在 bean 的公共方法中抛出异常来回滚事务吗?

    如果是这样(Q#2 的答案是肯定的)我是否必须通过在方法中声明异常来将异常从方法中抛出,或者只在方法中抛出异常就足够了?在同一方法本身内处理它? (我不想将异常传播到下一个级别。我只想回滚异常。)

提前致谢。 ;)

【问题讨论】:

【参考方案1】:

首先,没有异常回滚,它是事务的回滚。

    如果使用@ApplicationException(rollback=true) 抛出异常,则不必手动回滚事务。 Context.setRollbackOnly() 强制容器回滚事务,如果没有异常也是如此。 已检查异常本身不会回滚事务。它需要有注解@ApplicationException(rollback=true)。如果异常是RuntimeException 并且没有捕获到异常,它会强制容器回滚事务。但请注意,在这种情况下,容器将丢弃 EJB 实例。 如2.)中所述,如果你抛出RuntimeException,事务将自动回滚。如果您在代码中捕获到已检查异常,则必须使用setRollbackOnly 来回滚事务。

如需更多信息,请查看免费书籍Mastering EJB。它很好地描述了回滚场景,对download免费。

【讨论】:

"如果你在代码中捕获了一个检查异常,你必须使用 setRollbackOnly 来回滚事务。"你也可以抛出同样的异常并回滚事务吗? 出于类似原因,我只是在查看此答案,并想指出您链接到的书不再在该网站上提供完整的内容,而且它是从 2006 年开始的,所以它过时了,而且在 JEE5 和 JEE6 上下文中可能没有多大用处。 EJB 3.1 最终规范说应用程序异常是任何带有 @ApplicationException 注释的 ChechedException 或 RuntimeException 在我看来是异常糟糕的行为,如果有异常 IMO 显然应该回滚!有人知道为什么会这样吗? @EmmanuelTouzery:检查异常是方法签名的一部分,因此被视为“预期的”和非错误行为。现在,有些人使用检查异常作为方法的常规响应,而不是返回值。例如,它可以携带有关业务案例结果的信息。这就是为什么检查的异常默认情况下不会回滚事务(是签名的一部分),但 RuntimeExceptions 会(不是签名的一部分)。【参考方案2】:

关于如何防止注释性声明的已检查异常导致抛出回滚传播到“上层”的问题在这里尚未得到解答。

我认为这将需要一个围绕相关 EJB 的包装器,它可以吞下抛出的异常。 (换句话说:我认为自定义异常必须针对方法边界抛出(因此不能在方法内捕获和处理)并传播以产生事务效果——并且反过来也会导致 EJB 实例的破坏。)

【讨论】:

以上是关于EJB3 事务回滚的主要内容,如果未能解决你的问题,请参考以下文章

git 代码回滚回退到指定版本 并 提交

git 代码回滚回退到指定版本 并 提交

111

仅在 Asp.net 中回滚到特定迁移

什么是SQLSERVER事务处理和事务回滚?

spring事务会导致全局变量回滚么