使用外键约束更新列是否可以锁定引用的table?

Does updating a column with foregin key contraint can lock the referenced table?

我有一个 table,它在我的系统中被进程 A 大量更新。这是简化的 table:

db=# \d employee;
                                       Table "public.employee"
     Column      |            Type             | Collation | Nullable |                   Default
-----------------+-----------------------------+-----------+----------+---------------------------------------------
 id              | integer                     |           | not null | nextval('employee_id_seq'::regclass)
 name            | character varying           |           |          |

Indexes:
"employee_pkey" PRIMARY KEY, btree (id)

我有一个 table 引用 table:

db=# \d employee_property;
                                       Table "public.employee_property"
     Column      |            Type             | Collation | Nullable |                   Default
-----------------+-----------------------------+-----------+----------+---------------------------------------------
 id              | integer                     |           | not null | nextval('employee_property_id_seq'::regclass)
 type            | character varying           |           |          |
 value           | character varying           |           |          |
 employee_id     | integer                     |           | not null |

Indexes:
    "employee_property_pkey" PRIMARY KEY, btree (id)
    "employee_property_employee_id_type_value_key" UNIQUE CONSTRAINT, btree (employee_id, type, value)
    "ix_employee_property_employee_id" btree (employee_id)
Foreign-key constraints:
   "employee_property_employee_id_fkey" FOREIGN KEY (employee_id) REFERENCES employee(employee_id) ON DELETE CASCADE DEFERRABLE

我想了解如果我正在通过系统中的进程 B 大量更新 employee_property table,它是否会导致一些锁或任何其他可能影响进程 A 的副作用更新员工 table?

如果您在 employee_property 中插入一行或更新现有行的 employee_id 列,则会在新 employee_id 引用的行上放置一个 FOR KEY SHARE 锁到.

此锁将阻止任何并发尝试删除引用的 employee 行或更新任何 PRIMARY KEYUNIQUE 列。对不修改键列的锁定 employee 行的更新将起作用,因为它们只需要对该行进行 FOR NO KEY UPDATE 锁定,这与 FOR KEY SHARE.

兼容

这是因为 PostgreSQL 必须确保在修改 employee_property 的事务仍在进行时引用的行不会消失。仅检查 employee 中的引用行是不够的,因为仍在进行中的事务的影响在事务本身之外是不可见的。