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

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

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

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

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

提前致谢。 ;)

【问题讨论】:

    标签: java jakarta-ee transactions ejb-3.0 rollback


    【解决方案1】:

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

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

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

    【讨论】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      • 2012-12-30
      • 2011-09-19
      相关资源
      最近更新 更多