PG锁

一、表级锁定模式

(1)ACCESS SHAREAccessShareLock)

ACCESS EXCLUSIVE仅与锁定模式冲突。

SELECT命令在引用的表上获取此模式的锁。一般来说,任何读取表而不修改它的查询都会获取这种锁定模式。

(2)ROW SHARERowShareLock)

EXCLUSIVE与和ACCESS EXCLUSIVE锁定模式冲突。

SELECT FOR UPDATE 和命令在目标表上获取此模式的SELECT FOR SHARE(除了ACCESS SHARE在任何其他被引用但未选择的表上的锁FOR UPDATE/FOR SHARE)。

(4)ROW EXCLUSIVERowExclusiveLock)

SHARE与, SHARE ROW EXCLUSIVEEXCLUSIVE, 和ACCESS EXCLUSIVElock 模式冲突。

命令UPDATEDELETEINSERT在目标表上获取此锁定模式(除了ACCESS SHARE任何其他引用表上的锁定)。一般来说,任何修改表中数据的命令都会获取这种锁定模式。

(5)SHARE UPDATE EXCLUSIVEShareUpdateExclusiveLock)

SHARE UPDATE EXCLUSIVE与, SHARESHARE ROW EXCLUSIVEEXCLUSIVE, 和ACCESS EXCLUSIVElock 模式冲突。此模式保护表免受并发模式更改和VACUUM运行。

VACUUM(不带FULL)、ANALYZECREATE INDEX CONCURRENTLYCREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY以及某些ALTER INDEXALTER TABLE体获得(有关完整详细信息,请参阅这些命令的文档)。

(6)SHAREShareLock)

ROW EXCLUSIVE与, SHARE UPDATE EXCLUSIVESHARE ROW EXCLUSIVEEXCLUSIVE, 和ACCESS EXCLUSIVElock 模式冲突。此模式保护表免受并发数据更改的影响。

CREATE INDEX(无CONCURRENTLY获得。

(7)SHARE ROW EXCLUSIVEShareRowExclusiveLock)

ROW EXCLUSIVE与, SHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVE, 和ACCESS EXCLUSIVElock 模式冲突。此模式可保护表免受并发数据更改的影响,并且是自排的,因此一次只能有一个会话持有它。

CREATE TRIGGER某些形式的ALTER TABLE.

(8)EXCLUSIVEExclusiveLock)

ROW SHARE与, ROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVE, 和ACCESS EXCLUSIVElock 模式冲突。这种模式只允许并发ACCESS SHARE锁,即只有从表中读取可以与持有这种锁模式的事务并行进行。

被收购REFRESH MATERIALIZED VIEW CONCURRENTLY

(9)ACCESS EXCLUSIVEAccessExclusiveLock)

与所有模式的锁冲突(ACCESS SHAREROW SHAREROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVE, 和ACCESS EXCLUSIVE)。这种模式保证持有者是唯一以任何方式访问表的事务。

DROP TABLETRUNCATEREINDEXCLUSTERVACUUM FULL, 和REFRESH MATERIALIZED VIEW(不带CONCURRENTLY)命令获取。许多形式的ALTER INDEX并且ALTER TABLE也在这个级别获得了一个锁。这也是LOCK TABLE未明确指定模式的语句的默认锁定模式。

 

  二、行级

除了表级锁,还有行级锁,下面列出了PostgreSQL自动使用它们的上下文。有关行级锁冲突的完整表,请官网13.3 。请注意,一个事务可以在同一行上持有冲突的锁,即使在不同的子事务中也是如此;但除此之外,两个事务永远不能在同一行上持有冲突的锁。行级锁不影响数据查询;他们只阻止作家和储物柜到同一行。行级锁在事务结束或保存点回滚期间释放,就像表级锁一样。

(1)FOR UPDATE

FOR UPDATE导致SELECT语句检索到的行被锁定,就像更新一样。这可以防止它们被其他事务锁定、修改或删除,直到当前事务结束。也就是说,其他尝试UPDATEDELETESELECT FOR UPDATE,或这些行的事务将被阻塞SELECT FOR NO KEY UPDATE直到当前事务结束;相反,将等待已在同一行上运行任何这些命令的并发事务,然后将锁定并返回更新的行(或没有行,如果该行已被删除)。但是,在or事务中,如果要锁定的行在事务开始后发生了更改,则会引发错误。有关进一步的讨论,请参见官网第 13.4 节SELECT FOR SHARESELECT FOR KEY SHARESELECT FOR UPDATEREPEATABLE READSERIALIZABLE

FOR UPDATE锁定模式也由任何一行获得DELETE也由UPDATE修改某些列的值的 an 获得。目前,该UPDATE案例考虑的列集是那些具有唯一索引的列,可以在外键中使用(因此不考虑部分索引和表达式索引),但这可能会在未来发生变化。

(2)FOR NO KEY UPDATE

行为类似于FOR UPDATE,除了获取的锁较弱:此锁不会阻止SELECT FOR KEY SHARE尝试在相同行上获取锁的命令。这种锁定模式也被任何UPDATE没有获得FOR UPDATE锁的人获得。

(3)FOR SHARE

行为类似于FOR NO KEY UPDATE,除了它在每个检索到的行上获取共享锁而不是排他锁。共享锁会阻止其他事务在这些行上执行UPDATEDELETE但不会阻止它们执行SELECT FOR UPDATESELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE

(4)FOR KEY SHARE

行为类似于FOR SHARE,除了锁更弱:SELECT FOR UPDATE被阻塞,但不是SELECT FOR NO KEY UPDATE密钥共享锁阻止其他事务执行DELETE或任何UPDATE更改键值的事务,但不阻止其他事务UPDATE,也不会阻止SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE

PostgreSQL不记得内存中修改行的任何信息,因此一次锁定的行数没有限制。但是,锁定行可能会导致磁盘写入,例如,SELECT FOR UPDATE修改选定的行以将它们标记为锁定,因此会导致磁盘写入。

 

 

 

posted @ 2022-10-19 13:50  青空如璃  阅读(612)  评论(0编辑  收藏  举报