如何在PostgreSQL中模拟死锁?

时间:2014-04-01 01:21:20

标签: postgresql concurrency deadlock database-deadlocks

我是PostgreSQL的新手。我想为这个时间表模拟死锁: enter image description here

如何在PostgreSQL中模拟死锁?有可能吗?如何锁定特定列?
修改

    BEGIN;
UPDATE deadlock_demonstration
SET salary1=(SELECT salary1 
FROM deadlock_demonstration
WHERE worker_id = 1 
FOR UPDATE)+100
WHERE worker_id=1;
SELECT pg_sleep(5);
commit;
SELECT salary2 FROM deadlock_demonstration WHERE worker_id = 1 FOR UPDATE;

在另一个屏幕中,我已经运行了这个

    BEGIN;
UPDATE deadlock_demonstration
SET salary2=(SELECT salary1 
FROM deadlock_demonstration
WHERE worker_id = 1
FOR UPDATE)+200
WHERE worker_id=1;
SELECT pg_sleep(5);
commit;
SELECT salary1 FROM deadlock_demonstration WHERE worker_id = 1 FOR UPDATE;

为什么没有发生死锁?你能提出一个建议,我应该改变什么来刺激僵局?

2 个答案:

答案 0 :(得分:14)

  1. 并行打开两个连接,例如psql的两个实例或pgAdmin中的两个查询窗口(每个都有自己的会话)。
  2. 在每个连接中启动一个事务。 BEGIN;
  3. 依次运行相互冲突的命令。
  4. 在您提交之前,其中一个将回滚并出现死锁异常。
  5. 您可能想要回滚另一个。 ROLLBACK;
  6. 明确locking tables就像:

    一样简单
    LOCK tbl;
    

    锁定行可以通过以下方式完成:

    SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
    

    FOR SHAREDetails in the manual here.

    实施例

    您添加的示例无法解锁。两者都试图首先在同一个表的同一行上采用相同的锁。第二个将等待第一个完成。

    实际产生死锁的示例(行必须存在或不会进行锁定):

    Transaction 1                    Transaction 2
    BEGIN;
                                     BEGIN;
    SELECT salary1 
    FROM   deadlock_demonstration
    WHERE  worker_id = 1
    FOR    UPDATE;
                                     SELECT salary1 
                                     FROM   deadlock_demonstration
                                     WHERE  worker_id = 2
                                     FOR    UPDATE;
    UPDATE deadlock_demonstration
    SET    salary1 = 100
    WHERE  worker_id = 2;
    
                                     UPDATE deadlock_demonstration
                                     SET    salary1 = 100
                                     WHERE  worker_id = 1;
    
                         ... deadlock!
    

    结果

    OP用户3388473在验证我的解决方案后提供了此屏幕截图:

    enter image description here

答案 1 :(得分:0)

这是否意味着发生死锁?

没有。它确实意味着它所说的,你不能在pgsql clearly said here中使用commit