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 事务回滚的主要内容,如果未能解决你的问题,请参考以下文章