PostgreSQL - 锁



排他锁写锁阻止用户修改一行或整个表。UPDATE 和 DELETE 修改的行会自动被排它锁定,持续整个事务期间。这防止其他用户在事务提交或回滚之前更改该行。

用户必须等待其他用户的情况只发生在他们尝试修改同一行时。如果他们修改不同的行,则无需等待。SELECT 查询永远不需要等待。

数据库自动执行锁定。但是,在某些情况下,必须手动控制锁定。可以使用 LOCK 命令进行手动锁定。它允许指定事务的锁类型和范围。

LOCK 命令的语法

LOCK 命令的基本语法如下:

LOCK [ TABLE ]
name
 IN
lock_mode
  • 名称 - 要锁定的现有表的名称(可选的模式限定)。如果在表名前指定 ONLY,则只锁定该表。如果没有指定 ONLY,则锁定该表及其所有子表(如有)。

  • 锁模式 - 锁模式指定此锁与哪些锁冲突。如果没有指定锁模式,则使用 ACCESS EXCLUSIVE(最严格的模式)。可能的值为:ACCESS SHARE、ROW SHARE、ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE。

获得锁后,将在当前事务的剩余时间内保持该锁。没有 UNLOCK TABLE 命令;锁总是在事务结束时释放。

死锁

当两个事务都在等待对方完成其操作时,可能会发生死锁。虽然 PostgreSQL 可以检测到死锁并通过 ROLLBACK 结束它们,但死锁仍然可能带来不便。为了防止应用程序遇到此问题,请确保以这样的方式设计它们:它们将按相同顺序锁定对象。

建议锁

PostgreSQL 提供了创建具有应用程序定义含义的锁的方法。这些称为建议锁。由于系统不强制执行其使用,因此应用程序有责任正确使用它们。建议锁对于 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

上述消息指示该表已锁定,直到事务结束,要结束事务,您必须回滚或提交事务。

广告
© . All rights reserved.