【问题标题】:How can I detect that SessionContext.setRollbackOnly has been called in a method of an EJB?如何检测 SessionContext.setRollbackOnly 已在 EJB 的方法中被调用?
【发布时间】:2019-08-19 17:15:38
【问题描述】:

支持 bean (JSF) 调用 EJB 的方法,在该方法中启动事务。事务由 EJB 中的容器管理。 EJB 的方法可以通过调用setRollbackOnly 使事务无效。如何在 backing bean 中检测到它?

如果 EJB 方法在 EJB 方法中抛出系统异常而不是调用setRollbackOnly,那就很简单了。 setRollbackOnly 比抛出异常有什么优势?

【问题讨论】:

    标签: jakarta-ee transactions


    【解决方案1】:

    您不能直接在 JSF 托管 bean 中注入 EJB 上下文。

    只需通过公共方法公开当前事务状态。

    @Stateless
    public class MyEJB {
    
        @Resource
        private SessionContext context;
    
        // related getter / setter
        ...
    
       public boolean hasRolledBack() {
            return context.getRollbackOnly()
       }
    }
    

    如果事务被标记为回滚,您也可以自己抛出异常。

    关于您的第二个问题,事务已被跨国方法边界抛出的异常回滚,但它已在执行流程的后期某处被捕获。 (最好在你无法处理的错误上抛出一个 RuntimeException,这样没人会抓住它)

    【讨论】:

    • 感谢 Gab,但我不明白它如何解决我的问题。调用了 EJB 方法的 backing bean 如何知道事务是否已经回滚?能否给我一个backing bean检测回滚方法的粗略代码?
    • 如果我在setRollbackOnly之外抛出系统异常,我可以检测到回滚,但是,我看不到setRollbackOnly的实用性,因为只抛出系统异常就足以触发自动回滚.所以我想知道什么时候调用 setRollbackOnly 比抛出系统异常更好。
    • 1:只需将 EJB 注入支持 bean 并在其上调用 hasRolledBack() 2:在某处抛出异常,否则事务将不会回滚。只要找到它被捕获的地方
    • 感谢 Gab 的耐心等待。 1. 我认为 hasRolledBack() 不会在事务结束后返回 true (根据 javadoc,“当前事务”)。 2. 事务可能已经被 setRollbackOnly 回滚,没有抛出任何异常(因为没有满足管理规则)。
    • 啊确实,如果事务边界在 EJB 方法上,您将不得不在某处维护状态(例如线程局部变量)以便进一步访问。抛出异常看起来更优雅,恕我直言。
    猜你喜欢
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    相关资源
    最近更新 更多