如何使用 pgAdmin 测试 PostgreSQL 死锁

How to test PosgreSQL deadlocks with pgAdmin

我想使用 pgAdmin 4 测试 PostgreSQL 13 上的死锁,使用不同的锁类型和隔离级别。

到目前为止,我已经尝试打开两个 pgAdmin 选项卡并运行设置不同的事务块,如下所示:

--LOCK stats IN SHARE ROW EXCLUSIVE MODE;
--LOCK stats IN ROW SHARE MODE;
--LOCK stats IN ROW EXCLUSIVE MODE;
--SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
UPDATE stats SET clicks = 10 WHERE id = 59;
UPDATE stats SET leads = 10 WHERE id = 60;
UPDATE stats SET calls = 10 WHERE id = 59;
UPDATE stats SET reviews = 10 WHERE id = 60;
UPDATE stats SET saves = 10 WHERE id = 59;
UPDATE stats SET bookings = 10 WHERE id = 60;
COMMIT;
--SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
UPDATE stats SET clicks = 10 WHERE vendor_id = 60;
UPDATE stats SET leads = 10 WHERE vendor_id = 59;
UPDATE stats SET calls = 10 WHERE vendor_id = 60;
UPDATE stats SET reviews = 10 WHERE vendor_id = 59;
UPDATE stats SET saves = 10 WHERE vendor_id = 60;
UPDATE stats SET bookings = 10 WHERE vendor_id = 59;
COMMIT;

但令我惊讶的是,无论锁类型和隔离级别如何,行都可以完美地更新。阅读文档我假设默认的 table 锁是 ROW EXCLUSIVE 并且默认的事务隔离级别是 READ COMMITTED.

我想当 运行在不同的 pgAdmin 选项卡上运行时,两个事务块永远不会同时执行。这是预期的行为还是我做错了什么?我如何 运行 两个事务块在不同的线程中?

提前致谢。

无论如何,为了避免死锁,我在一个过程中实现了不同的事务(插入、更新),并在每个事务后使用 COMMIT 释放了锁。

为了测试它,我部署了 docker-compose 调用该过程的不同服务。此过程更新相同的 table 行并被重复调用。