亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何對 EJB3 事務提交或回滾做出反應?

如何對 EJB3 事務提交或回滾做出反應?

米琪卡哇伊 2021-08-04 10:17:18
我已將服務實現為無狀態會話 EJB (3.2) 以通過 JPA 存儲數據。此外,每次更新數據時,EJB 也會更新一個 Lucene 索引。會話 bean 是容器管理的。ejb 的代碼如下所示:@Stateless@LocalBeanpublic class DataService {    ....    public Data save(Data myData)  {        // JPA work....        ...        // update Lucene index        ....    }    ....} 我有不同的其他 BusinessService-EJB 調用這個 DataService EJB 來插入或更新數據。我無法控制 BusinessService-EJB 實現。由 BusinessService-ejb 啟動的事務可以包含對 DataService EJB 的 save() 方法的多次調用。@Stateless@LocalBeanpublic class SomeBusinessService {    @EJB    DataService dataService;    ....    public void process(....)  {        dataService.save(data1);        ...        dataService.save(data2);        ....    }    ....} 如果 BusinessService-EJBs 方法“進程”中斷,我的問題就會出現。DataService.save() 的每個方法調用都會更新給定數據對象的 Lucene 索引。但是,如果后面的調用之一失敗,則整個事務將回滾。我的 JPA 工作將按預期回滾(沒有數據寫入數據庫)。但是現在 Lucene 索引已經在事務被取消之前為 save() 方法的所有成功完整調用更新。所以我的問題是:我如何對我的 DataService EJB 中的這種情況做出反應?這甚至可能嗎?我看到使用 Statefull Session EJB 3.2 我可以使用注釋“ @AfterCompletion”來注釋方法。因此,我想這可能是僅當 @AfterCompletion 以“成功”調用時才編寫 lucene 索引的解決方案。但是這個注釋對于無狀態會話 EJB 是不允許的。我應該簡單地將我的 EJB 類型從無狀態更改為有狀態嗎?但這對我的 BusinessService-EJB 場景有何影響,它仍然是一個無狀態會話 EJB?這行得通嗎?我還擔心將我的 ejb 形式無狀態更改為有狀態會對性能產生影響?;蛘哂袥]有其他方法可以解決這個問題?例如,監聽器根據事務 ID 寫入日志,并在事務完全完成后更新 lucene 索引......?
查看完整描述

2 回答

?
有只小跳蛙

TA貢獻1824條經驗 獲得超8個贊

如果 lucene 索引不是事務性的,您將無法在發生故障時回滾。

或者有沒有其他方法可以解決這個問題?例如,監聽器根據事務 ID 寫入日志,并在事務完全完成后更新 lucene 索引......?

如果索引更新失敗了怎么辦?

整個事情必須在單個事務中,并且只有在其中的每個操作都成功時才必須提交該事務。這是保證數據一致性的唯一方法。

編寫一些測試來檢查當您使用 @Transactional 或使用 UserTransaction 注釋調用方方法時事務的反應。


查看完整回答
反對 回復 2021-08-04
?
手掌心

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


查看完整回答
反對 回復 2021-08-04
  • 2 回答
  • 0 關注
  • 152 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號