Synopsis
LOCK [ TABLE ]
name
LOCK [ TABLE ]
name
[, ...] IN
lockmode
MODE
这里
lockmode
可以是下列之一∶
ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE |
SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
输入
-
name
-
要锁定的现存的表.
-
ACCESS SHARE MODE
-
这是最小限制的锁模式,只与 ACCESS EXCLUSIVE 模式冲突。
它用于保护被查询的表免于被并行的
ALTER TABLE
,
DROP TABLE
和
VACUUM FULL
对同一表操作的语句修改。
-
ROW SHARE MODE
-
注意:
任何
SELECT...FOR UPDATE
语句执行时自动生效。
与 EXCLUSIVE 和 ACCESS EXCLUSIVE 锁模式冲突。
-
ROW EXCLUSIVE MODE
-
注意:
任何
UPDATE
,
DELETE
和
INSERT
语句执行时自动生效。
与 SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。
-
SHARE UPDATE EXCLUSIVE MODE
-
Note:
由
VACUUM
(没有
FULL
)
自动要求.
和SHARE UPDATE EXCLUSIVE,SHARE,SHARE ROW EXCLUSIVE,
EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突.这个模式保护一个表
不被并行的(事务进行)大纲修改和 VACUUM.
-
SHARE MODE
-
注意:
任何
CREATE INDEX
语句执行时自动附加。
共享锁住整个表.
与 ROW EXCLUSIVE,SHARE UPDATE EXCLUSIVE,
SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE
模式冲突。这个模式防止一个表的并行数据更新。
-
SHARE ROW EXCLUSIVE MODE
-
注意:
这个模式类似 EXCLUSIVE MODE,但是允许其他事务的 ROW SHARE 锁.
与 ROW EXCLUSIVE,SHARE UPDATE EXCLUSIVE,
SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和
ACCESS EXCLUSIVE 模式冲突。
-
EXCLUSIVE MODE
-
注意:
这个模式同样比 SHARE ROW EXCLUSIVE 更有约束力.
它阻塞所有并行的 ROW SHARE/SELECT... FOR UPDATE 查询。
与 ROW SHARE,ROW EXCLUSIVE,SHARE UPDATE EXCLUSIVE,
SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和
ACCESS EXCLUSIVE 模式冲突。
这个模式只允许并发的 ACCESS SHARE,也就是说只有从表中读取数据
可以和一个持有这个锁模式的事务并发执行.
-
ACCESS EXCLUSIVE MODE
-
注意:
由语句
ALTER TABLE
,
DROP TABLE
,
VACUUM FULL
执行时自动生效。这是最严格的约束锁,它
保护一个被锁定的表不被任何其他并行的操作更改。
注意:
一个不合格的
LOCK TABLE
同样要求这个锁模式
(例如,一条没有显式锁模式选项的命令)。
与所有锁模式冲突.
输出
-
LOCK TABLE
-
成功获取锁之后的返回.
-
ERROR
name
: Table does not exist.
-
如果
name
不存在,返回此信息.
描述
LOCK TABLE
控制一次事务的生命期内对某表的并行访问.
PostgreSQL
在可能的情况下尽可能使用最小约束的锁模式。
LOCK TABLE
在你需要时提供更有约束力的锁。
RDBMS
锁定使用下面术语:
-
EXCLUSIVE
-
一个排它锁禁止其它同类型的锁获得批准.(注意∶ROW EXCLUSIVE 模式
并不完全遵循这个命名规则,因为它是在表一级共享的;它只是相对于
要更新的行而言是排它的.)
-
SHARE
-
共享锁允许其它(事务)也持有同类型锁,但是禁止对应的 EXCLUSIVE
锁获得批准.
-
ACCESS
-
锁定表结构.
-
ROW
-
锁定独立的行.
例如,假设一个应用在 READ COMMITED 隔离级别上运行事务,
并且它需要保证在表中的数据在事务的运行过程中都存在。要实现这个目的,你
可以在查询之前对表使用 SHARE 锁模式进行锁定。这样将保护数据不被
并行修改并且为任何更进一步的对表的读操作提供实际的当前状态的数据,
因为 SHARE 锁模式与任何写操作需要的 ROW EXCLUSIVE 模式冲突,并且你的
LOCK TABLE
name
IN SHARE MODE
语句将等到所有并行的写操作提交或回卷后才执行。
因此,一旦你获得该锁,那么就不会存在未提交的写操作.
注意:
当运行在 SERIALIZABLE 隔离级别并且你需要读取真实状态的数据时,
你必须在执行任何 DML 语句
之前运行一个 LOCK TABLE 语句。
一个串行事务的数据视图将在其第一个 DML 语句开始的时候冻结住.
除了上面的要求外,如果一个事务准备修改一个表中的数据,
那么应该使用 SHARE ROW EXCLUSIVE 锁模式以避免死锁情况(当两个
并行的事务试图以 SHARE 模式锁住表然后试图更改表中的数据时,
两个事务(隐含的)都需要 ROW EXCLUSIVE 锁模式,而此模式与并行的
SHARE 锁冲突)。
继续上面的死锁(两个事务彼此等待)问题,
你应该遵循两个通用的规则以避免死锁条件:
-
事务应该以相同的顺序对相同的对象请求锁。
例如,如果一个应用更新行 R1 然后更新行 R2(在同一的事务里),
那么第二个应用如果稍后要更新行 R1 时不应该更新行 R2(在
同一事务里)。相反,它应该与第一个应用以相同的顺序更新行 R1 和 R2。
-
事务请求两个互相冲突的锁模式的前提:其中一个锁模式是自冲突的
(也就是说,一次只能被一个事务持有)。
如果涉及多种锁模式,那么事务应该总是最先请求最严格的锁模式。
这个规则的例子在前面的关于用
SHARE ROW EXCLUSIVE 模式取代 SHARE 模式的讨论中已经给出了。
注意:
PostgreSQL
的确检测死锁,
并将回卷至少一个等待的事务以解决死锁。
注意
LOCK ... IN ACCESS SHARE MODE
需要在目标表上有
SELECT
权限.所有其它形式的
LOCK
需要
UPDATE
和/或
DELETE
权限.
LOCK
只是在一个事务块的内部有用
(
BEGIN
...
COMMIT
),因为锁在事务结束的时候
马上被释放.出现在任意事务块外面的
LOCK
都自动生成
一个自包含的事务,因此该锁在获取之后马上被丢弃.
LOCK
只在事务内部使用.
用法
演示在往一个外键表上插入时在有主键的表上使用 SHARE 的锁:
BEGIN WORK;
LOCK TABLE films IN SHARE MODE;
SELECT id FROM films
WHERE name = 'Star Wars: Episode I - The Phantom Menace';
-- 如果记录没有返回则回卷
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;
兼容性
SQL92
在
SQL92
里面没有
LOCK TABLE
,可以使用
SET TRANSACTION
来声明当前事务的级别.
我们也支持这个,参阅
SET TRANSACTION
获取详细信息。
除了ACCESS SHARE,ACCESS EXCLUSIVE,和SHARE UPDATE EXCLUSIVE
锁模式外,
PostgreSQL
锁模式和
LOCK TABLE
语句都与那些在
Oracle
(TM) 里面的兼容。
|