2016-12-15 76 views
3

我正在分類賬模塊上工作。在這個過程中,我不得不爲了完成這些任務如何防止選擇和更新之間的競爭條件

  1. 從源(表1 RO​​W1)
  2. 從目的地(表1 2行)選擇平衡
  3. 修改餘額一些邏輯
  4. 更新平衡選擇平衡源(表1 RO​​W1)
  5. 爲目的地(表1 RO​​W2)更新平衡
  6. 提交更改
  7. 插入交易成TRANSAC表格。

在多線程環境中,線程在前一個線程更新和提交之前獲得餘額。 在Postgres中,對於正在訪問的行直到線程提交時都會執行鎖定。在這種情況下,我看到了一片黑暗。

嘗試使用同步塊爲整個模式。沒有幫助。 無法使用SELECT FROM UPDATE,因爲用於更改餘額的邏輯取決於其他操作。

這是一些日誌,在[1]線程去更新部分之前,其他線程收集現有的餘額。

[DEBUG] [2016-12-15 10:49:53,893] [1] - Src Ledger_book_idLB001 
[DEBUG] [2016-12-15 10:49:53,893] [1] - Src Balance2500.0 
[DEBUG] [2016-12-15 10:49:53,897] [1] - Dest Ledger_book_idLB002 
[DEBUG] [2016-12-15 10:49:53,897] [1] - Dest Balance0.0 
[DEBUG] [2016-12-15 10:49:53,898] [15] - Src Ledger_book_idLB001 
[DEBUG] [2016-12-15 10:49:53,898] [15] - Src Balance2500.0 
[DEBUG] [2016-12-15 10:49:53,899] [16] - Src Ledger_book_idLB001 
[DEBUG] [2016-12-15 10:49:53,899] [16] - Src Balance2500.0 
[DEBUG] [2016-12-15 10:49:53,900] [16] - Dest Ledger_book_idLB002 
[DEBUG] [2016-12-15 10:49:53,900] [15] - Dest Ledger_book_idLB002 

任何幫助表示讚賞:)請評論如果有任何具體的疑問的情況。

+0

你可以使用'serializable'隔離級別。 –

+0

如果你正在更新'source',是什麼使它成爲'source'?來源和目的地有什麼區別? –

+0

@EvanCarroll來源我的意思是源帳戶...我試圖從借方來源和信貸在目的地的借方。 – Vamsidhar

回答

0

From the docs

當鎖定子句出現在子SELECT,鎖定是那些返回到由子查詢外部查詢的行。由於來自外部查詢的條件可能被用於優化子查詢的執行,所以這可能涉及比檢查單獨的子查詢更少的行。

這樣你就可以做到這一點...

你也應該閱讀CTE的頁面,尤其是DATA-MODIFYING

WITH s1 AS (
    SELECT balance FROM source 
    FOR UPDATE 
), s2 AS (
    SELECT balance destination 
    FOR UPDATE 
), u1 AS (
    UPDATE source SET balance = ... 
    WHERE... -- potential join to S2 if you need destination 
    RETURNING -- whatever you need (if anything) 
), u2 AS (
    UPDATE source SET balance = ... 
    WHERE... -- potential join to S1 if you need source 
    RETURNING -- whatever you need (if anything) 
) 
INSERT INTO transactions (foo,date) VALUES (bar,now());