2013-06-18 35 views
4

目前,我有一種JPA實體用於某種任務。有些進程會寫入該表,並且計劃的進程將對該任務起作用,並在準備就緒時更改狀態。我需要確定任務的優先順序,並在失敗時以降低的頻率重試它們。我的環境是通過Hibernate + MySQL + XA事務的GlassFish 3 + JPA。在中期內,該項目將通過Spring解決方案(使用Jetty等)取代GlassFish。如何使用JPA編寫生產者 - 消費者

它以某種方式得到了這個工作,但我對它並不滿意:我得到了OptimisticLockExceptions,看起來我沒有在某些點上獲得正確的事務,而且GlassFish上的JPA計時器也有點混亂你需要可變的時間。

我有這種感覺,我在這裏使用了錯誤的工具,而且我應該使用一些成熟穩定的設計,而不是一起杵在一起。使用JPA實體似乎是沉重的,但原始JDBC看起來更糟糕的選擇。當然,我想避免沉重的圖書館依賴性,但也許我忽略了針對特定問題的簡單「罐裝」解決方案(這看起來並不常見)。

[編輯]

爲了澄清:我不會改變用途的情況下(我甚至不具備的代碼了),我只是想獲得一些一般原則,以「做正確「(TM)下一次。爲了回答ben75提出的問題:工作人員可能是多線程的,而且我需要小型交易,因爲它應該一直運行 - 也許幾個月。

+0

你的工作進程是單線程嗎?誰確定優先級(工人或生產者或...)?你什麼時候獲得OptimisticLocking(在任務執行結束時或...)?在整個任務執行期間你有單一交易嗎? – ben75

回答

1

我認爲你只需要嘗試從上面看到事物以便識別過程中的角色&檢測任務的創建者,任務的處理器和優先級控制器之間的依賴關係。之後,爲每個角色設計乾淨的可重用EJBs/Services。

有時,對於只需要10-20秒的相對較短的任務,強制用戶使用異步EJB(搜索@Asynchronous)而不是創建任務更有意義。

關於OptimisticLockExpcetions:這些可能發生是因爲數據同時發生更改,這可能是由任務使用者的其他線程中的一個或由更改數據的客戶端引起的。找出原因,如果這是第一種情況,請糾正錯誤。當然,如果你提供一些代碼或解釋如何運作,你會得到更多的幫助。

處理任務時:我會用悲觀鎖取回任務實體,以便另一個線程不會開始處理相同的任務。

所以我想你的過程很複雜,你需要一個更好/更靈活的設計。

+0

這些已經是一些很好的想法,例如我從來沒有嘗試過'@ Asynchronous'。 – Landei