Предотвращение состояния гонки параллелизма при обновлении из подзапроса в Postgres - PullRequest
0 голосов
/ 04 февраля 2020

Я хотел подтвердить, что правильно понимаю документы, поскольку они относятся к следующему примеру.

Учитывая таблицу с именем 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.

Являются ли эти жизнеспособные решения проблемы и, если да, одним из них? подходить лучше, чем другой с точки зрения производительности?

...