postgres中FOR KEY SHARE的实际用途是什么?

Har*_*nam 8 postgresql

我无法理解我将在哪里实际使用它。根据这里的文档它说

行为与 FOR SHARE 类似,只是锁较弱:SELECT FOR UPDATE 被阻止,但 SELECT FOR NO KEY UPDATE 不会被阻止。键共享 锁会阻止其他事务执行 DELETE 或任何 更改键值的UPDATE ,但不会阻止其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATE、SELECT FOR SHARE 或 SELECT FOR KEY SHARE。

但我尝试过,它允许所有可能的更新。我什至尝试更换钥匙。可能是我无法理解文档所指的键(我认为这是这个答案中的外键,因为它没有像文档中所说的那样被阻止,所以我尝试更新所有内容并且一切都正常工作而没有被阻止)。我通过使用两个模拟两个并发事务的 psql 终端进行了实验。

交易1

db1=> begin;
BEGIN
db1=> SELECT * from table_base FOR key share;
 base_id | foreign_id | nonkey1 
---------+------------+---------
 112 |          2 | plaexpl
  21 |          2 | harish
 111 |          2 | harish
(3 rows)

db1=> select * from table_foreign ;
foreign_id |  value  
------------+---------
      2 | val2
     12 | val1new
     44 | newval3
(3 rows)

db1=> \d table_base 
                  Table "public.table_base"
 Column   |         Type          | Collation | Nullable | Default 
 ------------+-----------------------+-----------+----------+---------
 base_id    | integer               |           |          | 
 foreign_id | integer               |           |          | 
 nonkey1    | character varying(50) |           |          | 
 Foreign-key constraints:
  "table_base_foreign_id_fkey" FOREIGN KEY (foreign_id) REFERENCES 
 table_foreign(foreign_id) ON UPDATE CASCADE
Run Code Online (Sandbox Code Playgroud)

交易2

db1=> begin;
BEGIN
db1=> UPDATE table_base set base_id = 221 where base_id=21;
UPDATE 1
db1=> UPDATE table_base set foreign_id = 12 where nonkey1='harish';
UPDATE 2
db1=> UPDATE table_base set nonkey1='newharish' where nonkey1='harish';
UPDATE 2
db1=> end;
COMMIT
db1=> SELECT * from table_base;
 base_id | foreign_id |  nonkey1  
---------+------------+-----------
     112 |          2 | plaexpl
     111 |         12 | newharish
     221 |         12 | newharish
(3 rows)

db1=> begin;
BEGIN
db1=> UPDATE table_foreign set foreign_id = 33 where value = 'val1new';
UPDATE 1
db1=> UPDATE table_foreign set value ='newvalfor33' where foreign_id = 33;
UPDATE 1
db1=> end;
COMMIT
db1=> SELECT * from table_foreign ;
 foreign_id |    value    
------------+-------------
          2 | val2
         44 | newval3
         33 | newvalfor33
(3 rows)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

有关上例中表格的更多信息 在此输入图像描述 如果它允许所有更新,那么“FOR KEY SHARE”和普通“SELECT”之间有什么区别(除了它阻止 SELECT FOR UPDATE)。这有什么实际用途?

Lau*_*lbe 13

FOR KEY SHARE当修改具有外键约束的表时最有用:引用的行(在远程表上)将(自动)接收这样的锁,以便不能同时修改引用的键。

您看不到任何效果,因为您的表不包含PRIMARY KEYorUNIQUE约束。

  • 是的,但不是主键列。 (2认同)