Может ли обновление столбца с противопоказанием ключа foregin заблокировать ссылочную таблицу?
У меня есть одна таблица, которая сильно обновляется в моей системе процессом А. Это упрощенная таблица:
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)
И у меня есть таблица, которая ссылается на эту таблицу:
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
Я пытаюсь понять, обновляю ли я employee_property
таблицы в значительной степени с помощью процесса B в системе, может ли это вызвать некоторые блокировки или любые другие побочные эффекты, которые могут повлиять на процесс A, который обновляет таблицу сотрудников?
1 ответ
Если вы вставите строку в employee_property
или обновить employee_id
столбец существующей строки, FOR KEY SHARE
замок ставится на новый ряд employee_id
относится к.
Эта блокировка заблокирует любую одновременную попытку удалить указанную employee
грести или обновлять любой PRIMARY KEY
или же UNIQUE
колонны. Обновления к заблокированным employee
строка, которая не изменяет ключевой столбец, будет работать, потому что они требуют только FOR NO KEY UPDATE
блокировка на ряд, который совместим с FOR KEY SHARE
,
Причина этого заключается в том, что PostgreSQL должен гарантировать, что указанная строка не может исчезнуть во время транзакции, которая изменяет employee_property
все еще в процессе. Просто проверяя ссылки на строки в employee
этого будет недостаточно, поскольку эффекты транзакции, которая все еще выполняется, не видны вне самой транзакции.