锁定Postgres功能

时间:2014-10-20 07:17:00

标签: postgresql synchronization locking

我们说我有一个交易表和 transaction_summary 表。我创建了以下触发器来更新 transaction_summary 表。

CREATE OR REPLACE FUNCTION doSomeThing() RETURNS TRIGGER AS
$BODY$
DECLARE 
rec_cnt bigint;
BEGIN
    -- lock rows which have to be updated
    SELECT count(1) from (SELECT 1 FROM transaction_summary WHERE receiver = new.receiver FOR UPDATE) r INTO rec_cnt ;    
    IF rec_cnt = 0 
    THEN 
        -- if there are no rows then create new entry in summary table
        -- lock whole table
        LOCK TABLE "transaction_summary" IN ACCESS EXCLUSIVE MODE;
        INSERT INTO transaction_summary( ... ) VALUES ( ... );
    ELSE
        UPDATE transaction_summary SET ... WHERE receiver = new.receiver;
    END IF;

    SELECT count(1) from (SELECT 1 FROM transaction_summary WHERE sender = new.sender FOR UPDATE) r INTO rec_cnt ;    
    IF rec_cnt = 0 
    THEN 
        LOCK TABLE "transaction_summary" IN ACCESS EXCLUSIVE MODE;
        INSERT INTO transaction_summary( ... ) VALUES ( ... );
    ELSE
        UPDATE transaction_summary SET ... WHERE sender = new.sender;
    END IF;   

    RETURN new;
END;
$BODY$
language plpgsql;

问题:会有死锁吗?根据我的理解僵局,可能会发生这样的事情:

_________
|__table__| <- executor #1 waits on executor #2 to be able to lock the whole table AND 
|_________| executor #2 waits on executor #1 to be able to lock the whole table
|_________|
|_________| <- row is locked by executor #1
|_________| 
|_________| <- row is locked by executor #2

似乎只有选项是每次在事务开始时锁定整个表。

0 个答案:

没有答案