LOCK

LOCK

锁表。

概要

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

其中lockmode是以下之一:

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

描述

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

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

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

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

参数

name
要锁定的现有表的名称(可以是schema限定)。 如果指定ONLY,则仅锁定该表。 如果未指定ONLY,则表及其所有子表(如果有)将被锁定。 (可选)可以在表名称后指定*,以明确指示包括子表。
如果给出了多个表,则表将按照LOCK TABLE命令中指定的顺序一张一张地锁定。
lockmode
锁定模式指定与该锁定冲突的锁定。 如果未指定锁定模式,则使用限制最大的ACCESS EXCLUSIVE模式。 锁定方式如下:
  • ACCESS SHARE — 仅与ACCESS EXCLUSIVE锁定模式冲突。 SELECT命令在引用的表上获得此模式的锁定。 通常,任何仅读取表而不修改表的查询都将获得此锁定模式。
  • ROW SHARE — 与EXCLUSIVEACCESS EXCLUSIVE锁定模式冲突。 SELECT FOR SHARE命令自动在目标表上获得此模式的锁定(除了在已引用但未选择FOR SHARE的任何其他表上的ACCESS SHARE锁定之外)。
  • ROW EXCLUSIVE — 与SHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE锁定模式冲突。 INSERTCOPY命令自动在目标表上获取此锁定模式(除了对任何其他引用表的ACCESS SHARE锁定外), 请参见注解
  • SHARE UPDATE EXCLUSIVE — 与SHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE锁定模式冲突。 此模式可防止表发生并发schema更改和VACUUM运行。 由VACUUM(无FULL)在堆表和ANALYZE上获取。
  • SHARE — 与ROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARE ROW EXCLUSIVE, EXCLUSIVEACCESS EXCLUSIVE锁定模式冲突。 此模式可防止表发生并发数据更改。 由CREATE INDEX自动获取。
  • SHARE ROW EXCLUSIVE — 与ROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE锁定模式冲突。 任何Greenplum数据库命令都不会自动获取此锁定模式。
  • EXCLUSIVE — 与ROW SHAREROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE锁定模式冲突。 此模式仅允许并发的ACCESS SHARE锁定,即,只有从表中读取的数据才能与持有该锁定模式的事务并行进行。 对于Greenplum数据库中的UPDATESELECT FOR UPDATEDELETE, 此锁定模式是自动获取的(与常规PostgreSQL相比,限制性更强)。 看注解
  • ACCESS EXCLUSIVE — 与所有模式的锁定(ACCESS SHAREROW SHAREROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE)冲突。 这种模式保证了持有者是唯一以任何方式访问表的事务。 由ALTER TABLEDROP TABLETRUNCATEREINDEXCLUSTERVACUUM FULL命令自动获取。 这是未明确指定模式的LOCK TABLE语句的默认锁定模式。 VACUUM(无FULL)也会在处理过程中在追加优化表上短暂获取此锁。
Note: 默认情况下,Greenplum数据库为堆表上的DELETEUPDATESELECT FOR UPDATE操作获取表上的EXCLUSIVE锁。 启用全局死锁检测器后,堆表上操作的锁定模式为ROW EXCLUSIVE。 请参阅全局死锁检测
NOWAIT
指定LOCK TABLE不等待任何冲突的锁被释放:如果不等待就无法立即获取指定的锁,则事务中止。

注解

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

LOCK TABLE在事务块之外是无用的:该锁定将仅在LOCK语句完成时就释放。 因此,如果在事务块外部使用LOCK,Greenplum数据库将报告错误。 使用BEGINEND定义事务块。

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

示例

在执行films_user_comments表中的插入操作时,在films表上获得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;

兼容性

SQL标准中没有LOCK TABLE,而是使用SET TRANSACTION来指定事务的并发级别。 Greenplum数据库也支持这一点。

除了ACCESS SHAREACCESS EXCLUSIVESHARE UPDATE EXCLUSIVE锁定模式外, Greenplum数据库锁定模式和LOCK TABLE语法与Oracle中的兼容。