Jakarta ee 如何使无状态会话bean能够感知事务?
如何在无状态会话bean中通知事务需要回滚? 例如,我有一个无状态EJB,它正在用一些业务数据更新LuceneIndex。该方法在具有多个EJB调用的事务中调用。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
当一些较新的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更改所需的信息