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 也不會包含“未刷新”的文檔。此行為等同于事務模型“已提交讀”。
添加回答
舉報