我知道程序员可以选择在执行数据库操作时获取explicit locks,但是我想更清楚地了解Postgres在执行常见操作(例如{{ 1}}。
答案 0 :(得分:1)
好吧,让我们看看。
首先,打开两个连接。在第一个字段中(填写表格等,并使用适合您数据库的值):
=# BEGIN;
=# UPDATE table SET field = x WHERE id = y;
现在,切换到另一个连接。使用pg_stat_activity
查找另一个连接的pid
:
=# SELECT pid FROM pg_stat_activity WHERE query = 'UPDATE table SET field = x WHERE id = y;';
pid
------
1684
(1 row)
很显然,pid
(进程ID)将有所不同。
好的,现在使用pid
找出正在使用的锁:
=# SELECT * FROM pg_locks WHERE pid = 1684;
locktype | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction | pid | mode | granted | fastpath
---------------+----------+----------+--------+--------+------------+---------------+---------+--------+----------+--------------------+-----+------------------+---------+----------
relation | 16384 | 16385 | [null] | [null] | [null] | [null] | [null] | [null] | [null] | 4/10730 | 743 | RowExclusiveLock | t | t
virtualxid | [null] | [null] | [null] | [null] | 4/10730 | [null] | [null] | [null] | [null] | 4/10730 | 743 | ExclusiveLock | t | t
transactionid | [null] | [null] | [null] | [null] | [null] | 1440 | [null] | [null] | [null] | 4/10730 | 743 | ExclusiveLock | t | f
(3 rows)
现在,两个ExclusiveLock
都在交易和虚拟交易中。我们可以忽略这些问题-无论交易如何,它们都会在几乎每笔交易中出现。
但是RowExclusiveLock
有一个数据库和与之关联的关系。关系就是您要更新的表。
因此,对您问题的正确答案是RowExclusiveLock
。
现在,您可以ROLLBACK
或COMMIT
进行更新交易并进行清理。如果您想知道SELECT FOR UPDATE
时使用的锁类型,可以遵循相同的步骤。
请注意,这是最简单的情况:更新一张表的一行。更复杂的更新可能具有更多与之关联的锁。