2015-08-28 29 views
0

我有一個消息驅動bean,它通過EntityManager與數據庫通信。 EM通過@PersistenceContext注入,就像正常一樣。我想立即將更改刷新到實體,而無需等待MDB完全完成對給定消息的處理。EJB - 在MDB中提交併刷新

例如:

MDB's onMessage() { 
    Foo f = em.find(Foo.class, 123); 
    f.setNewStatus("Performing work!"); 
    em.merge(f); 
    em.flush(); 
    ... 
    // Continue doing a lot of work... 
    ... 

    f.setNewStatus("Done!"); 
    em.merge(f); 
    em.flush(); 
} 

的問題是,我從來沒有看到 「執行工作!」來自MDB上下文之外的狀態(例如,通過直接登錄到數據庫並檢查元組的值)。

這似乎與交易有關。從在線資料看,這聽起來像一個事務在onMessage()的上下文中開始,並且在方法完成之前不會被提交。因此,由於我們最終編寫了「完成!」,所以中間狀態永遠不會被執行。它會覆蓋PersistentContext中的Foo值。

有沒有解決這類問題的方法?一些方法來控制交易的上下文?

回答

0

我想你想實現的是在事務提交之前查看事務之外的變化。那麼這是唯一可能的事務隔離設置爲讀未提交,我不認爲是您的數據庫中的默認值。

你可以做的是添加方法,將記錄您的數據,與屬性:@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

在這種情況下,容器將不得不暫停當前事務,創造條件,在這種方法中執行新的,當它結束時,主要交易將被恢復。

+0

@Scarpul - 感謝您的迴應。我也遇到了這個功能,並開始實施它。然而,有一個警告,我沒有上面列出(爲了更廣義的問題)。實際上,我將EntityManager交給一個單獨的僅用於業務邏輯的類來完成實際工作(而不是將其全部結合到MDB中)。我在使用POJO類中的@TransactionAttribute時遇到了一些麻煩 - 我將進一步調查,最糟糕的情況是我可能必須將POJO類轉換爲無狀態EJB。我會盡快報告結果。 – Jmoney38

+0

似乎無法正常工作... – Jmoney38

+0

您是否創建了EJB?它是在執行處理事務的EJB調用時圍繞該方法編寫的代碼。從EJB內部直接調用方法也沒用,不確定你是如何構造你的代碼的。你應該在網上找到很多關於這個的例子。 –