Jakarta ee 如何使无状态会话bean能够感知事务?

Jakarta ee 如何使无状态会话bean能够感知事务?,jakarta-ee,transactions,ejb,Jakarta Ee,Transactions,Ejb,如何在无状态会话bean中通知事务需要回滚? 例如,我有一个无状态EJB,它正在用一些业务数据更新LuceneIndex。该方法在具有多个EJB调用的事务中调用。 当一些较新的EJB回滚事务时,如何告知我此问题,以便我能够回滚已编写的LuceneIndex条目?您可以通过注入对当前EJBContext的引用,然后查询它来完成此操作: @Stateless public class LuceneDriver { @Resource private EJBContext e

如何在无状态会话bean中通知事务需要回滚? 例如,我有一个无状态EJB,它正在用一些业务数据更新LuceneIndex。该方法在具有多个EJB调用的事务中调用。
当一些较新的EJB回滚事务时,如何告知我此问题,以便我能够回滚已编写的LuceneIndex条目?

您可以通过注入对当前EJBContext的引用,然后查询它来完成此操作:

 @Stateless
 public class LuceneDriver {

     @Resource
     private EJBContext ejbContext;

     public void performLuceneStuff(...) {
         try {
             ...
             // update lucene data
             ...
             // update some business data
             ...
         } catch (BusinessException e) {
             if (ejbContext.getRollbackOnly()) {
                 // rollback lucene changes
             }
         }
     }

     ...

}

如果会话EJB不是事务性的,则在出现故障时将无法回滚。这是因为缺少无状态会话EJB的状态信息

解决这个问题的一个解决方案是使用@statefulsessionbean来实现javax.ejb.SessionSynchronization接口。此接口允许您在回滚时做出反应


另一个解决方案是使用由主事务通过JPA编写的自定义事件日志条目。通过这些事件日志条目,另一个无状态会话EJB可以验证是否存在新的事件日志条目,以及是否可以对其作出反应。如果回滚了trancaction,事务管理器也将删除未提交的事件日志项。因此,这是一个将非事务性功能与基于JPA容器的事务耦合的解决方案。请参阅问题:

但是如果回滚是在我的方法performLuceneStuff完成后由同一事务中的另一个EJB初始化的,该怎么办?这不重要。EJB始终具有高度的事务感知能力。ejbContext.getRollbackOnly唯一不起作用的时间是另一个EJB启动了新事务。只有在您显式配置新事务时,它才会启动。我可能仍然站在软管上。。。我期望的是注册回调方法的机制,当同一事务中的其他人(而不是我的bean)失败时,事务管理器会调用该回调方法。这样我就可以撤销我已经写好的索引文件。好的,慢慢地我意识到我的错误。由于缺少状态信息,无法调用无状态EJB进行回滚。也许我需要某种资源适配器来管理我的Lucene索引问题……如果您不介意管理生命周期,您可以使用实现接口的@statefulbean。这提供了一个回调。您可以使用EJB的状态来提供回滚Lucene更改所需的信息