我有一個名為 user_table 的表,它有 2 列:id(整數)和 data_value(整數)。
以下是兩個最終結果相同的事務:
-- TRANSACTION 1
BEGIN;
UPDATE user_table
SET data_value = 100
WHERE id = 0;
UPDATE user_table
SET data_value = 200
WHERE id = 1;
COMMIT;
-- TRANSACTION 2
BEGIN;
UPDATE user_table AS user_with_old_value SET
data_value = user_with_new_value.data_value
FROM (VALUES
(0, 100),
(1, 200)
) AS user_with_new_value(id, data_value)
WHERE user_with_new_value.id = user_with_old_value.id;
COMMIT;
我想知道在行上應用的鎖是否有區別。
如果我理解正確,事務 1 將首先鎖定用戶 0,然后鎖定用戶 1,然后釋放兩個鎖。
但是事務 2 做了什么?它是做同樣的事情還是做:鎖定用戶 0 和用戶 1,然后釋放兩個鎖?
存在差異,因為如果我有兩個并發事務,如果我將查詢寫為第一個事務,我可能會遇到死鎖問題。但是如果我像第二個那樣寫我的交易,我會遇到死鎖問題嗎?
如果它做同樣的事情,有沒有辦法撰寫這個事務,以便在事務開始時,在做任何事情之前,事務檢查它需要更新的每一行,等到所有這些行都沒有被鎖定,然后鎖定同時所有行?
鏈接: 第二個事務的語法來自:Update multiple rows in same query using PostgreSQL
uj5u.com熱心網友回復:
兩個事務都鎖定相同的兩行,并且都可能陷入死鎖。不同的是,第一個事務總是按一定的順序鎖定兩行。
如果您的目標是避免死鎖,那么第一個事務會更好:如果您制定規則,任何事務必須先更新較低的用戶id,那么沒有這樣兩個事務可以相互死鎖(但它們仍然可以與其他事務死鎖)不遵守該規則)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/454918.html
標籤:PostgreSQL 僵局
