我有以下存储过程
CREATE OR REPLACE FUNCTION testFunction(iRowID1 integer, iRowID2 integer) RETURNS void AS $$
BEGIN
UPDATE Table1 SET Value1=Value1+1 WHERE rowID=iRowID1;
UPDATE Table1 SET Value1=Value1-1 WHERE rowID=iRowID2;
END;
$$ LANGUAGE plpgsql;
如果我同时运行以下两个命令
SELECT testFunction(1,2);
SELECT testFunction(2,1);
我发现其中一个命令出现死锁检测错误。有没有办法避免这种僵局?
答案 0 :(得分:2)
我现在无法对此进行测试,因为目前我无法访问PostgreSQL数据库,但从理论上说它应该可以正常工作,因为如果以相同的顺序锁定事物并且永远不会升级,则始终可以避免死锁锁定级别(例如,将读锁定升级为写锁定。)
按特定顺序执行更新:
CREATE OR REPLACE FUNCTION testFunction(iRowID1 integer, iRowID2 integer) RETURNS void AS $$
BEGIN
IF iRowID1 < iRowID2 THEN
UPDATE Table1 SET Value1=Value1+1 WHERE rowID=iRowID1;
UPDATE Table1 SET Value1=Value1-1 WHERE rowID=iRowID2;
ELSE
UPDATE Table1 SET Value1=Value1-1 WHERE rowID=iRowID2;
UPDATE Table1 SET Value1=Value1+1 WHERE rowID=iRowID1;
END IF
END;
$$ LANGUAGE plpgsql;
这将始终以数字升序更新行,因此在您的示例中,第1行将始终在第2行之前更新,第二次调用无法在第一次调用完成之前开始更新。