LOCK
LOCK¶
锁表。
- 语法
- ``` sql
LOCK [TABLE] [ONLY] name [ * ] [, …] [IN lockmode MODE] [NOWAIT]
其中`lockmode`是以下之一: ``` sql ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
- 描述
-
LOCK TABLE
获取表级别的锁,必要时等待释放任何冲突的锁。 如果指定了NOWAIT
,则LOCK TABLE
不会等待获取所需的锁:如果无法立即获取,则命令将中止并发出错误。一旦获得,该锁将在当前事务的其余部分保持。 没有UNLOCK TABLE
命令;锁始终在事务结束时释放。当自动获取引用表的命令的锁时,SeaboxMPP数据库始终使用限制最小的锁模式。
LOCK TABLE
提供了可能需要更多限制性锁定的情况。例如,假设应用程序在Read Committed隔离级别上运行事务,并且需要确保表中的数据在事务期间保持稳定。为此,可以在查询之前在表上获得SHARE
锁定模式。这将防止并发数据更改,并确保后续读取表时都能看到已提交数据的稳定视图,因为
SHARE
锁定模式与写入者获取的ROW EXCLUSIVE
锁冲突, 并且您的LOCK TABLE name IN SHARE MODE
语句将等待直到任何并发持有者ROW EXCLUSIVE
模式的锁将锁定提交或回滚。因此,一旦获得了锁,就不会有未提交的未完成的写操作。此外,在释放锁之前,任何人都无法开始。为了在
REPEATABLE READ
或SERIALIZABLE
隔离级别下运行事务时达到类似的效果,必须在执行任何SELECT
或数据修改语句之前执行LOCK TABLE
语句。当REPEATABLE READ
或SERIALIZABLE
事务的数据视图的第一个SELECT
或数据修改语句开始时,将被冻结。事务中稍后的LOCK TABLE
仍将阻止并发写入 - 但不能确保事务读取的内容与最新的提交值相对应。如果此类事务要更改表中的数据,则应使用
SHARE ROW EXCLUSIVE
锁定模式而不是SHARE
模式。这样可以确保一次仅运行一个这种类型的事务。否则,可能会导致死锁:两个事务可能都同时获取SHARE
模式,然后又无法获取ROW EXCLUSIVE
模式来实际执行其更新。 请注意,事务自身的锁永远不会发生冲突,因此,当事务拥有SHARE
模式时,它可以获取ROW EXCLUSIVE
模式,但如果其他人拥有SHARE
模式,则不行。为避免死锁,请确保所有事务以相同的顺序获取对相同对象的锁定,并且如果单个对象涉及多个锁定模式,则事务应始终首先获取限制性最强的模式。 - 参数
-
该SQL命令参数说明见下
name
- 要锁定的现有表的名称(可以是schema限定)。 如果指定
ONLY
,则仅锁定该表。如果未指定ONLY
,则表及其所有子表(如果有)将被锁定。(可选)可以在表名称后指定*
,以明确指示包括子表。如果给出了多个表,则表将按照LOCK TABLE
命令中指定的顺序一张一张地锁定。 lockmode
-
锁定模式指定与该锁定冲突的锁定。 如果未指定锁定模式,则使用限制最大的
ACCESS EXCLUSIVE
模式。 锁定方式如下:-
ACCESS SHARE — 仅与
ACCESS EXCLUSIVE
锁定模式冲突。SELECT
命令在引用的表上获得此模式的锁定。通常,任何仅读取表而不修改表的查询都将获得此锁定模式。 -
ROW SHARE — 与
EXCLUSIVE
和ACCESS EXCLUSIVE
锁定模式冲突。SELECT FOR SHARE
命令自动在目标表上获得此模式的锁定(除了在已引用但未选择FOR SHARE
的任何其他表上的ACCESS SHARE
锁定之外)。 -
ROW EXCLUSIVE — 与
SHARE
,SHARE ROW EXCLUSIVE
,EXCLUSIVE
和ACCESS EXCLUSIVE
锁定模式冲突。INSERT
和COPY
命令自动在目标表上获取此锁定模式(除了对任何其他引用表的ACCESS SHARE
锁定外)。 -
SHARE UPDATE EXCLUSIVE — 与
SHARE UPDATE EXCLUSIVE
,SHARE
,SHARE ROW EXCLUSIVE
,EXCLUSIVE
和ACCESS EXCLUSIVE
锁定模式冲突。此模式可防止表发生并发schema更改和VACUUM
运行。由VACUUM
(无FULL
)在堆表和ANALYZE
上获取。 -
SHARE — 与
ROW EXCLUSIVE
,SHARE UPDATE EXCLUSIVE
,SHARE ROW EXCLUSIVE, EXCLUSIVE
和ACCESS EXCLUSIVE
锁定模式冲突。 此模式可防止表发生并发数据更改。 由CREATE INDEX
自动获取。 -
SHARE ROW EXCLUSIVE — 与
ROW EXCLUSIVE
,SHARE UPDATE EXCLUSIVE
,SHARE
,SHARE ROW EXCLUSIVE
,EXCLUSIVE
和ACCESS EXCLUSIVE
锁定模式冲突。任何SeaboxMPP数据库命令都不会自动获取此锁定模式。 -
EXCLUSIVE — 与
ROW SHARE
,ROW EXCLUSIVE
,SHARE UPDATE EXCLUSIVE
,SHARE
,SHARE ROW EXCLUSIVE
,EXCLUSIVE
和ACCESS EXCLUSIVE
锁定模式冲突。此模式仅允许并发的ACCESS SHARE
锁定,即,只有从表中读取的数据才能与持有该锁定模式的事务并行进行。对于SeaboxMPP数据库中的UPDATE
,SELECT FOR UPDATE
和DELETE
,此锁定模式是自动获取的。 -
ACCESS EXCLUSIVE — 与所有模式的锁定(
ACCESS SHARE
,ROW SHARE
,ROW EXCLUSIVE
,SHARE UPDATE EXCLUSIVE
,SHARE
,SHARE ROW EXCLUSIVE
,EXCLUSIVE
和ACCESS EXCLUSIVE
)冲突。 这种模式保证了持有者是唯一以任何方式访问表的事务。 由ALTER TABLE
,DROP TABLE
,TRUNCATE
,REINDEX
,CLUSTER
和VACUUM FULL
命令自动获取。这是未明确指定模式的LOCK TABLE
语句的默认锁定模式。VACUUM
(无FULL
)也会在处理过程中在列存表上短暂获取此锁。
注意:默认情况下,SeaboxMPP数据库为堆表上的
DELETE
,UPDATE
和SELECT FOR UPDATE
操作获取表上的EXCLUSIVE
锁。启用全局死锁检测器后,堆表上操作的锁定模式为ROW EXCLUSIVE
。 -
NOWAIT
- 指定
LOCK TABLE
不等待任何冲突的锁被释放:如果不等待就无法立即获取指定的锁,则事务中止。
- 注解
-
LOCK TABLE ... IN ACCESS SHARE MODE
需要对目标表具有SELECT
权限。所有其他形式的LOCK
都需要表级UPDATE
,DELETE
或TRUNCATE
权限。LOCK TABLE
在事务块之外是无用的:该锁定将仅在LOCK
语句完成时就释放。因此,如果在事务块外部使用LOCK
,SeaboxMPP数据库将报告错误。使用BEGIN
和END
定义事务块。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
来指定事务的并发级别。SeaboxMPP数据库也支持这一点。除了
ACCESS SHARE
,ACCESS EXCLUSIVE
和SHARE UPDATE EXCLUSIVE
锁定模式外,SeaboxMPP数据库锁定模式和LOCK TABLE
语法与Oracle中的兼容。 - 相关SQL命令
BEGIN
,SET TRANSACTION
,SELECT