2012-10-24 54 views
2

我有以下情況。寫兩個線程寫同一個實體的不同字段

一個業務實體(BE)由2個線程異步提供的2個部分組成。 示例:我們的BE具有字段id和A,B,C - 全部位於數據庫中的一個表中。當實體存儲到數據庫中時,Id按順序生成。 B是唯一的字段,它在數據庫中存在約束。 Process1提供字段A和B. Process2提供字段B和C.因此,在兩個過程完成後,我們應該在表中填充所有列中的一行。

使這項工作成功的好方法是什麼?

什麼是現在做:

在每一個過程中,我們首先選擇從表中的所有值,其中B列中值是什麼,我們現在有。 (如果有的話 - 這意味着其他進程已保存它的一部分)。如果有什麼東西,它會在缺少的列上得到豐富,並持續不斷。如果什麼都沒有 - 我們只是堅持我們擁有的東西。但是當所有這些都完成時,可能會發生其他進程完成它的工作,並且當我們堅持我們的實體時,我們得到ConstraintViolationException並且hibernate將事務標記爲回滾。缺少的列仍然丟失。

+2

沒有源代碼。沒有明確的具體問題。我得到螺旋讀你的問題。請澄清並至少在理論上證明問題。 – TheBlastOne

回答

-1

我會做這樣

  • 負載或啓動線程
  • 啓動線程之前創建的實體,它給每個
  • 更新它在這兩個線程
  • 時都完成後,保存到db
+0

從兩個線程訪問hibernate實體可能不是一個好主意。觸發加載懶惰的東西很容易,這會導致併發訪問會話,無法正確處理會話。此外,問題中提到的兩個線程都訪問字段B,創建另一個地雷字段。 –

+0

當然,我沒有想到延遲加載的集合,但這很容易防止與渴望提取。屬性B不是問題,因爲兩個線程都在同一個實體上工作,B是唯一的,因此兩個線程的B必須相同。我甚至會在線程啓動之前設置B,並在Map中使用它作爲線程的關鍵字,以便找到它進行更新。 – Firo

0

您首先必須決定如何處理衝突。爲此回答以下問題:

如果進程1在進程2運行時更改實體,則2的結果仍然有效嗎?還是應該重新運行?

如果進程1在進程2運行時更新字段B,那麼進程2是否應該覆蓋它?或者只保留過程1的值?

當然,這些問題也應該回答1和2互換。

如果您以某種方式實施流程,使其採用原始實體並生成新的修改後的起始實體,您可以使用一個隊列來添加所有這些結果,並使用一個應用這些結果的流程改變你的數據庫。

在特定情況下,更簡單的方法可能是可能的,但這是我在您的問題描述的一般情況下推薦的方法。

相關問題