How to simulate deadlock in PostgreSQL?

烂漫一生 提交于 2019-12-01 14:57:05

问题


I am new for PostgreSQL. I want to simulate deadlock for this schedule:

How to simulate deadlock in PostgreSQL? Is it possible at all? How to lock particular column?
EDIT:

    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;

In another screen, I have run this

    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;

Why deadlock is not happening? Can you give a suggestion, what I should change in order to stimulate deadlock?


回答1:


  1. Open two connections in parallel, like two instances of psql or two query windows in pgAdmin (each has its own session).
  2. Start a transaction in each connection. BEGIN;
  3. Run mutually conflicting commands in turns.
  4. Before you can commit, one of the two will be rolled back with a deadlock exception.
  5. You may want to roll back the other. ROLLBACK;

Explicitly locking tables is as simple as:

LOCK tbl;

Locking rows can be done with:

SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;

Or FOR SHARE etc. Details in the manual here.

Example

Your added example cannot deadlock. Both try to take the same lock on the same row of the same table first. The second will wait for the first to finish.

Example to actually produce a deadlock (rows must exist or no lock will be taken):

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!

Result

The OP user3388473 contributed this screenshot after verifying my solution:




回答2:


Does this mean deadlock happened?

No. It does mean what it says, you can not use commit in pgsql, clearly said here.



来源:https://stackoverflow.com/questions/22775150/how-to-simulate-deadlock-in-postgresql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!