I have one table, which is heavily updated in my system by process A. This is the simplified 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)
And I have a table which is referencing that 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
I am trying to understand if I am updating the employee_property
table heavily by process B in the system, might it cause some locks or any other side effects which might affect the process A which updates the employee table?
If you insert a row in
employee_property
or update theemployee_id
column of an existing row, aFOR KEY SHARE
lock is placed on the row the newemployee_id
refers to.This lock will block any concurrent attempt to delete the referenced
employee
row or update anyPRIMARY KEY
orUNIQUE
columns. Updates to the lockedemployee
row that do not modify a key column will work, because they only require aFOR NO KEY UPDATE
lock on the row, which is compatible withFOR KEY SHARE
.The reason for this is that PostgreSQL must ensure that the referenced row cannot vanish while the transaction that modifies
employee_property
is still in progress. Simply checking for referencing rows inemployee
won't be enough, because the effects of a transaction that is still in progress are not visible outside the transaction itself.