D-K*_*D-K 4 postgresql amazon-rds
给定以下 SQL,“ONLY”、“OPERATOR(pg_catalog.=)”和“FOR KEY SHARE”有什么作用?
SELECT 1
FROM ONLY "public"."acmeinstanceinfo" x
WHERE "widgetid" OPERATOR(pg_catalog.=) $1
FOR KEY SHARE OF x
Run Code Online (Sandbox Code Playgroud)
我对 Microsoft SQL 服务器有相当多的经验,但对 PostgreSQL 的经验为零。对这个查询正在做什么的任何见解都会很棒。
这是在具有外键的表中插入或更新行的效果。请参阅以下示例:
CREATE TABLE a (id integer PRIMARY KEY);
CREATE TABLE b (id integer REFERENCES a);
INSERT INTO a VALUES (1);
Run Code Online (Sandbox Code Playgroud)
现在在一个会话中,启动一个事务并锁定该行a:
BEGIN;
SELECT id FROM a FOR UPDATE;
id
????
1
(1 row)
Run Code Online (Sandbox Code Playgroud)
然后,在另一个会话中,尝试在 中插入一行b:
INSERT INTO b VALUES (1); -- hangs!
Run Code Online (Sandbox Code Playgroud)
发生了什么?
在SELECT ... FOR UPDATE采取了FOR UPDATE在该行锁定a。
在INSERT必须确保没有并发事务可以删除引用的行a(或修改其任何键列),以避免不一致。
为此,它运行
SELECT 1
FROM ONLY "public"."a" x
WHERE "id" OPERATOR(pg_catalog.=) 1
FOR KEY SHARE OF x;
Run Code Online (Sandbox Code Playgroud)
这里ONLY确保没有其他表受到影响,如果它a是继承层次结构的一部分,并且OPERATOR(pg_catalog.=)是模式限定运算符的PostgreSQL 语法(因为运算符也受search_path,PostgreSQL 必须确保使用正确的=运算符)。
由于FOR UPDATE和FOR KEY SHARE锁冲突(参见文档),第二个会话被阻止。
您可以通过使用SELECT ... FOR NO KEY UPDATE代替来避免该块SELECT ... FOR UPDATE。仅当您计划更新主键或唯一键列或打算删除该行时才需要后者。
| 归档时间: |
|
| 查看次数: |
368 次 |
| 最近记录: |