PostgreSQL 中的锁定模式与另一种锁定模式冲突到底是什么意思?

问题描述 投票:0回答:1

在表 13.2 中。冲突的锁定模式在这里我们看到ROW EXCLUSIVE与SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE和ACCESS EXCLUSIVE锁定模式冲突,但它不与自身冲突。 考虑以下示例。 我同时启动 2 个事务 T1 和 T2。

然后在T1我执行以下命令:

my_db=# begin;
BEGIN
my_db=*# update t set color = 'green' where id = 2;
UPDATE 1

然后在T2我执行以下命令:

my_db=# begin;
BEGIN
my_db=*# update t set color = 'blue' where id = 2;
之后

T2 被锁定

然后我选择关系的所有锁t

my_db=# select lock.locktype,lock.mode,lock.transactionid,lock.relation::regclass as relation,lock.virtualxid from pg_locks as lock where locktype = 'relation';
 locktype |       mode       | transactionid |  relation   | virtualxid
----------+------------------+---------------+-------------+------------
 relation | RowExclusiveLock |               | t_color_idx |
 relation | RowExclusiveLock |               | t           |
 relation | RowExclusiveLock |               | t_color_idx |
 relation | RowExclusiveLock |               | t           |
 relation | AccessShareLock  |               | pg_locks    |
(5 rows)

my_db=#

我看到只有RowExclusiveLockAccessShareLock模式的锁。 但T2已被锁定。 但根据表13.2。冲突的锁定模式 RowExclusiveLock 与自身不冲突

好吧,RowExclusiveLockACCESS EXCLUSIVE冲突。 考虑新的示例:我同时启动 2 个new 事务 T1 和 T2。 在T1:

my_db=# begin;
BEGIN
my_db=*#
my_db=*# alter table t alter column color TYPE varchar(400);
ALTER TABLE
my_db=*#

在T2:

my_db=# begin;
BEGIN
my_db=*# update t set color = 'black' where id = 2;

T2 在之后变得锁定,就像第一个示例一样。

然后我选择关系的所有锁t

my_db=# select lock.locktype,lock.mode,lock.transactionid,lock.relation::regclass as relation,lock.virtualxid from pg_locks as lock where locktype = 'relation';
 locktype |        mode         | transactionid |  relation   | virtualxid
----------+---------------------+---------------+-------------+------------
 relation | AccessShareLock     |               | pg_locks    |
 relation | RowExclusiveLock    |               | t           |
 relation | AccessShareLock     |               | t_color_idx |
 relation | AccessExclusiveLock |               | t_color_idx |
 relation | AccessExclusiveLock |               | 3028689     |
 relation | ShareLock           |               | t           |
 relation | AccessExclusiveLock |               | t           |
(7 rows)

my_db=#

我看到还有AccessExclusiveLock。 根据表13.2。冲突的锁定模式 RowExclusiveLockAccessExclusiveLock 冲突。 但是第二个示例中的行为与第一个示例中的行为相同:T2 被锁定

那么,

  1. PostgreSQL 中“锁定模式与另一种锁定模式冲突”是什么意思?
  2. 为什么RowExclusiveLock不与其本身冲突,却阻塞了另一个事务?

我预计冲突意味着锁定。

postgresql transactions locking isolation-level
1个回答
0
投票

如果两种锁定模式发生冲突,则两个不同的事务不能在同一个对象上同时获取它们。第一个到来的获取锁,第二个被阻塞,直到第一个释放锁(提交)。

SHARE
锁是防止表上所有并发数据修改的锁,由
CREATE INDEX
获取。
ROW EXCLUSIVE
是想要在表上执行
INSERT
UPDATE
DELETE
的事务所采用的锁。出于明显的原因,它与
SHARE
锁冲突,并且它与自身不冲突,因为允许两个并发事务同时修改同一个表中的数据(只要它们不尝试修改相同的行,这由行锁处理)。

© www.soinside.com 2019 - 2024. All rights reserved.