LOCK

LOCK-锁定桌子

Synopsis

LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]

where lockmode is one of:

    ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
    | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

Description

LOCK TABLE获取表级锁,必要时 await 释放任何冲突的锁。如果指定了NOWAIT,则LOCK TABLE不会 await 获取所需的锁:如果无法立即获取它,该命令将中止并发出错误。一旦获得,该锁将在当前事务的其余部分中保留。 (没有UNLOCK TABLE命令;锁始终在事务结束时释放.)

锁定视图后,视图定义查询中出现的所有关系也将以相同的锁定模式递归锁定。

当自动获取引用表的命令的锁时,PostgreSQL 始终使用限制最小的锁模式。 LOCK TABLE提供了可能需要更多限制性锁定的情况。例如,假设应用程序以READ COMMITTED隔离级别运行事务,并且需要确保表中的数据在事务期间保持稳定。为此,您可以在查询之前在表上获得SHARE锁定模式。这将防止并发数据更改,并确保随后的表读取能够看到已提交数据的稳定视图,因为SHARE锁定模式与编写器获取的ROW EXCLUSIVE锁冲突,并且LOCK TABLE name IN SHARE MODE语句将 await,直到ROW EXCLUSIVE模式锁的任何并发持有者提交或回滚。因此,一旦获得了锁,就不会有未提交的未完成的写操作。此外,在您释放锁之前,任何人都无法开始。

为了在REPEATABLE READSERIALIZABLE隔离级别上运行事务时达到类似的效果,必须在执行任何SELECT或数据修改语句之前执行LOCK TABLE语句。 REPEATABLE READSERIALIZABLE事务的数据视图在其第一个SELECT或数据修改语句开始时将被冻结。事务中的LOCK TABLE仍将阻止并发写入-但不能确保事务读取的内容与最新的提交值相对应。

如果此类事务要更改表中的数据,则应使用SHARE ROW EXCLUSIVE锁定模式而不是SHARE模式。这样可以确保一次仅运行一次这种类型的事务。否则,可能会导致死锁:两个事务可能都同时获取SHARE模式,然后又无法获取ROW EXCLUSIVE模式来实际执行其更新。 (请注意,事务自身的锁永远不会发生冲突,因此,当事务拥有SHARE模式时,它可以获取ROW EXCLUSIVE模式,但是如果其他人拥有SHARE模式则不能.)为避免死锁,请确保所有事务在同一对象上的相同对象上获得锁。Sequences,并且如果单个对象涉及多个锁定模式,则事务应始终首先获取限制性最强的模式。

有关锁定模式和锁定策略的更多信息,请参见Section 13.3

Parameters

  • name

    • 要锁定的现有表的名称(可选,由模式限定)。如果在表名之前指定了ONLY,则仅该表被锁定。如果未指定ONLY,则该表及其所有后代表(如果有)将被锁定。 (可选)可以在表名称后指定*,以明确指示包括后代表。

命令LOCK TABLE a, b;等效于LOCK TABLE a; LOCK TABLE b;。这些表按照LOCK TABLE命令中指定的 Sequences 被一对一锁定。

  • lockmode

    • 锁定模式指定与该锁定冲突的锁定。锁定模式在Section 13.3中描述。

如果未指定锁定模式,则使用限制性最强的模式ACCESS EXCLUSIVE

  • NOWAIT

    • 指定LOCK TABLE不应 await 释放任何冲突的锁:如果不 await 就无法立即获取指定的锁,则事务中止。

Notes

LOCK TABLE ... IN ACCESS SHARE MODE要求对目标表具有SELECT特权。 LOCK TABLE ... IN ROW EXCLUSIVE MODE要求目标表具有INSERTUPDATEDELETETRUNCATE特权。 LOCK的所有其他形式都需要表级UPDATEDELETETRUNCATE特权。

在视图上执行锁定的用户必须在视图上具有相应的特权。此外,视图的所有者必须对基础基本关系具有相关特权,但是执行锁定的用户不需要对基础基本关系具有任何权限。

LOCK TABLE在事务块之外是无用的:该锁将仅在语句完成之前保持不变。因此,如果在事务块外部使用LOCK,PostgreSQL 将报告错误。使用BEGINCOMMIT(或ROLLBACK)定义事务块。

LOCK TABLE只处理表级锁,因此涉及ROW的模式名称都是错误的。这些模式名称通常应理解为指示用户意图获取锁定表中的行级锁定的意图。同样,ROW EXCLUSIVE模式是可共享的表锁。请记住,就LOCK TABLE而言,所有锁定模式都具有相同的语义,只是在哪些模式与哪个模式冲突的规则上有所不同。有关如何获取实际的行级锁的信息,请参见SELECT参考文档中的Section 13.3.2锁定条款

Examples

在执行向外键表的插入操作时,在主键表上获得SHARE锁:

BEGIN WORK;
LOCK TABLE films IN SHARE MODE;
SELECT id FROM films
    WHERE name = 'Star Wars: Episode I - The Phantom Menace';
-- Do ROLLBACK if record was not returned
INSERT INTO films_user_comments VALUES
    (_id_, 'GREAT! I was waiting for it for so long!');
COMMIT WORK;

在执行删除操作时,对主键表进行SHARE ROW EXCLUSIVE锁定:

BEGIN WORK;
LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
DELETE FROM films_user_comments WHERE id IN
    (SELECT id FROM films WHERE rating < 5);
DELETE FROM films WHERE rating < 5;
COMMIT WORK;

Compatibility

SQL 标准中没有LOCK TABLE,而是使用SET TRANSACTION指定事务的并发级别。 PostgreSQL 也支持。有关详情,请参见SET TRANSACTION

ACCESS SHAREACCESS EXCLUSIVESHARE UPDATE EXCLUSIVE锁定模式外,PostgreSQL 锁定模式和LOCK TABLE语法与 Oracle 中存在的那些兼容。