PostgreSQL - 锁定
Locks 或 Exclusive Locks 或 Write Locks 阻止用户修改一行或整个表。 由 UPDATE 和 DELETE 修改的行会在事务期间自动独占锁定。 这可以防止其他用户在事务提交或回滚之前更改行。
用户必须等待其他用户的唯一时间是当他们试图修改同一行时。 如果他们修改不同的行,则无需等待。 SELECT 查询永远不必等待。
数据库自动执行锁定。 然而,在某些情况下,必须手动控制锁定。 手动锁定可以通过使用 LOCK 命令来完成。 它允许指定事务的锁类型和范围。
LOCK 命令的语法
LOCK 命令的基本语法如下 −
LOCK [ TABLE ] name IN lock_mode
name − 要锁定的现有表的名称(可选模式限定)。 如果在表名之前指定了 ONLY,则仅锁定该表。 如果未指定 ONLY,则表及其所有后代表(如果有)被锁定。
lock_mode − 锁定模式指定此锁定与哪些锁定冲突。 如果未指定锁定模式,则使用最严格的 ACCESS EXCLUSIVE 模式。 可能的值为:ACCESS SHARE、ROW SHARE、ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE。
一旦获得,该锁将在当前事务的剩余部分中保持。 没有 UNLOCK TABLE 命令; 锁总是在事务结束时释放。
死锁
当两个事务相互等待完成其操作时,可能会发生死锁。 虽然 PostgreSQL 可以检测到它们并以 ROLLBACK 结束它们,但死锁仍然很不方便。 为防止您的应用程序遇到此问题,请确保将它们设计为以相同的顺序锁定对象。
建议锁定
PostgreSQL 提供了创建具有应用程序定义含义的锁的方法。 这些被称为advisory lock建议锁定。 由于系统不强制使用它们,因此由应用程序正确使用它们。 建议锁对于不适合 MVCC 模型的锁定策略很有用。
例如,建议锁定的常见用途是模拟所谓的“平面文件”数据管理系统典型的悲观锁定策略。 虽然存储在表中的标志可以用于相同目的,但建议锁定更快,避免表膨胀,并且在会话结束时由服务器自动清理。
示例
考虑表COMPANY的记录如下 −
testdb# select * from COMPANY; id | name | age | address | salary ----+-------+-----+-----------+-------- 1 | Paul | 32 | California| 20000 2 | Allen | 25 | Texas | 15000 3 | Teddy | 23 | Norway | 20000 4 | Mark | 25 | Rich-Mond | 65000 5 | David | 27 | Texas | 85000 6 | Kim | 22 | South-Hall| 45000 7 | James | 24 | Houston | 10000 (7 rows)
以下示例以 ACCESS EXCLUSIVE 模式锁定 testdb 数据库中的 COMPANY 表。 LOCK 语句仅在事务模式下工作 −
testdb=#BEGIN; LOCK TABLE company1 IN ACCESS EXCLUSIVE MODE;
上面给出的 PostgreSQL 语句将产生以下结果 −
LOCK TABLE
上面的消息表明在事务结束之前表被锁定,并且要完成事务,您必须回滚或提交事务。