使用外键约束更新列是否可以锁定引用的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 KEY
或 UNIQUE
列。对不修改键列的锁定 employee
行的更新将起作用,因为它们只需要对该行进行 FOR NO KEY UPDATE
锁定,这与 FOR KEY SHARE
.
兼容
这是因为 PostgreSQL 必须确保在修改 employee_property
的事务仍在进行时引用的行不会消失。仅检查 employee
中的引用行是不够的,因为仍在进行中的事务的影响在事务本身之外是不可见的。
我有一个 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 KEY
或 UNIQUE
列。对不修改键列的锁定 employee
行的更新将起作用,因为它们只需要对该行进行 FOR NO KEY UPDATE
锁定,这与 FOR KEY SHARE
.
这是因为 PostgreSQL 必须确保在修改 employee_property
的事务仍在进行时引用的行不会消失。仅检查 employee
中的引用行是不够的,因为仍在进行中的事务的影响在事务本身之外是不可见的。