Я хотел подтвердить, что правильно понимаю документы, поскольку они относятся к следующему примеру.
Учитывая таблицу с именем requests
с двумя столбцами даты с именами accepted_at
и denied_at
, у меня есть два процесса, которые обновляют эти записи.
Процесс 1:
UPDATE requests SET denied_at = NOW() WHERE accepted_at IS NULL AND denied_at IS NULL
Процесс 2:
UPDATE requests
SET accepted_at = NOW()
FROM (
SELECT requests.id WHERE denied_at IS NULL
) as r
WHERE requests.id = r.id AND requests.accepted_at IS NULL
Правильно ли, что на Postgres 10 со стандартным уровнем изоляции READ COMMITTED
это склонно к состоянию гонки, когда я могу получить request
, который столбцы accepted_at
и denied_at
заполнены, если Процесс 1 одновременно выполняется с Процессом 2?
Я предполагаю, что может произойти следующее (при условии, что каждый процесс имеет свой собственный сеанс):
- Процесс 2 ВЫБИРАЕТ (в подзапросе) запись, в которой
denied_at
равен нулю. - Процесс 1 ОБНОВЛЯЕТ ту же запись и устанавливает значение для
denied_at
. - Процесс 2 ОБНОВЛЕНИЯ (во внешнем запросе) той же записи и устанавливает значение для
accepted_at
.
Если мое предположение верно, я считаю, что есть несколько способов исправить этот сценарий:
1) Я могу добавить AND requests.denied_at IS NULL
к предложению WHERE
внешнего запроса в процессе 2. T он заставит PG перепроверить условие и исключить строки, которые не соответствуют.
2) Я могу изменить подзапрос Процесса 2, чтобы использовать SELECT FOR UPDATE
. Это заставит процесс 2 ждать, если процесс 1 обновляет текущую строку. После обновления процесса 1 процесс 2 перепроверяет предложение WHERE
подзапроса и исключает строки, которые не совпадают.
3) Я могу обернуть процесс 2 транзакцией и установить уровень изоляции до SERIALIZABLE
, и в этом случае Процесс 2 будет сталкиваться с ошибкой в любое время, когда Процесс 1 обновляет любую строку, которую также пытается обновить Процесс 2.
Являются ли эти жизнеспособные решения проблемы и, если да, одним из них? подходить лучше, чем другой с точки зрения производительности?