2 回答
TA贡献1824条经验 获得超8个赞
如果 lucene 索引不是事务性的,您将无法在发生故障时回滚。
或者有没有其他方法可以解决这个问题?例如,监听器根据事务 ID 写入日志,并在事务完全完成后更新 lucene 索引......?
如果索引更新失败了怎么办?
整个事情必须在单个事务中,并且只有在其中的每个操作都成功时才必须提交该事务。这是保证数据一致性的唯一方法。
编写一些测试来检查当您使用 @Transactional 或使用 UserTransaction 注释调用方方法时事务的反应。
TA贡献1942条经验 获得超3个赞
我通过以下方式解决了这个问题:
而不是在我的方法 DataService.save(data) 期间直接更新 Lucene 索引,我只是使用相同的事务使用 JPA 创建一个新的 eventLogEntry。
@Stateless
@LocalBean
public class DataService {
....
public Data save(Data myData) {
// JPA work....
...
// Write a JPA eventLog entry indicating to update Lucene index
....
}
....
}
现在,每当客户端调用 lucene 搜索方法时,我都会运行一个刷新方法来根据事件日志条目更新我的 lucene 索引:
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
public void flush() {
Query q = manager.createQuery("SELECT eventLog FROM EventLog AS eventLog" );
Collection<EventLog> result = q.getResultList();
if (result != null && result.size() > 0) {
for (EventLog eventLogEntry : result) {
.... update lucen index for each entry
.......
// remove the eventLogEntry.
manager.remove(eventLogEntry);
}
}
}
有了注解TransactionAttributeType.REQUIRES_NEW,flush() 方法将只读取已经提交的 eventLog 条目。
因此,客户端只会在 Lucene 索引中看到已提交的更新。即使在来自我的一个 BusinessService-EJB 的事务期间,lucene 也不会包含“未刷新”的文档。此行为等同于事务模型“已提交读”。
添加回答
举报