[英]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 = 100或amount = -50的競爭條件?
如果是,是否可以通過以下方式修復:
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.