PostgreSQL执行“ UPDATE”时获得的锁的确切类型是什么?

时间:2019-10-25 21:02:43

标签: postgresql locking

我知道程序员可以选择在执行数据库操作时获取explicit locks,但是我想更清楚地了解Postgres在执行常见操作(例如{{ 1}}。

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

现在,您可以ROLLBACKCOMMIT进行更新交易并进行清理。如果您想知道SELECT FOR UPDATE时使用的锁类型,可以遵循相同的步骤。

请注意,这是最简单的情况:更新一张表的一行。更复杂的更新可能具有更多与之关联的锁。