簡體   English   中英

使用 READ_COMMITED 同時更新字段

[英]Concurrently updating a field with READ_COMMITED

假設我們已經在表中有以下行:

INSERT INTO some_table (id, amount) VALUES (1, 0);

使用READ_COMMITED同時運行以下查詢:

INSERT INTO some_table (id, amount) VALUES (1, 0)
ON CONFLICT DO
  UPDATE some_table SET amount=amount+100 WHERE id=1;
INSERT INTO some_table (id, amount) VALUES (1, 0)
ON CONFLICT DO
  UPDATE some_table SET amount=amount-50 WHERE id=1;

如果他們都讀取初始(提交的)amount=0 並且一個事務覆蓋另一個事務的結果,他們是否會遇到結果amount = 100amount = -50的競爭條件?

如果是,是否可以通過以下方式修復:

  1. 切換到 REPEATABLE_READ?
  2. 像這樣使用“FOR UPDATE”
WITH updating as (
    SELECT id, amount FROM some_table FOR UPDATE
)
INSERT INTO some_table (id, amount) VALUES (1, 0)
ON CONFLICT DO
  UPDATE some_table t SET t.amount=updating.amount+100 WHERE t.id=updating.id;
WITH updating as (
    SELECT id, amount FROM some_table FOR UPDATE
)
INSERT INTO some_table (id, amount) VALUES (1, 0)
ON CONFLICT DO
  UPDATE some_table t SET t.amount=updating.amount-50 WHERE t.id=updating.id;

INSERT... ON CONFLICT不受競爭條件的影響。 其中一個UPDATE會先鎖定該行,另一個必須等待,但無論順序如何,最后的數量都會比開始時多 50。

請注意, WHERE id = 1是不必要的,因為UPDATE只會影響與INSERT沖突的一行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM