Как вы можете использовать "Для обновления пропустить заблокирован" в postgres без блокировки строк во всех таблицах, используемых в запросе?
Если вы хотите использовать функцию SELECT FOR UPDATE SKIP LOCKED для postgres, чтобы гарантировать, что два разных пользователя, читающие из таблицы и утверждающие задачи, не будут заблокированы друг другом, а также не получат задачи, уже прочитанные другим пользователем:
Объединение используется в запросе для получения задач. Мы не хотим, чтобы любая другая таблица имела блокировку на уровне строк, кроме таблицы, содержащей основную информацию. Пример запроса ниже - блокировка только строк в таблице -'task'в запросе ниже
SELECT v.someid , v.info, v.parentinfo_id, v.stage FROM task v, parentinfo pi WHERE v.stage = 'READY_TASK'
AND v.parentinfo_id = pi.id
AND pi.important_info_number = (
SELECT MAX(important_info_number) FROM parentinfo )
ORDER BY v.id limit 200 for update skip locked;
Теперь, если пользователь A извлекает около 200 строк этой таблицы, пользователь B должен иметь возможность получить другой набор из 200 строк.
РЕДАКТИРОВАТЬ: Согласно комментарию ниже, запрос будет изменен на:
SELECT v.someid , v.info, v.parentinfo_id, v.stage FROM task v, parentinfo pi WHERE v.stage = 'READY_TASK'
AND v.parentinfo_id = pi.id
AND pi.important_info_number = (
SELECT MAX(important_info_number) FROM parentinfo) ORDER BY v.id limit 200 for update of v skip locked;
Как лучше разместить заказ так, чтобы строки были упорядочены? Несмотря на то, что порядок вступит в силу, если несколько пользователей вызовут эту команду, все же следует поддерживать некоторую последовательность порядка возвращаемых строк.
Кроме того, это также гарантирует, что несколько потоков, вызывающих один и тот же запрос выбора, получат другой набор строк, или блокировка выполняется только для команд обновления?
2 ответа
Немного поэкспериментировал с этим - несколько запросов на выборку в конечном итоге будут получать различный набор строк. Также order by обеспечивает порядок полученного конечного результата.
Да,
FOR UPDATE OF "TABLE_NAME" SKIP LOCKED
заблокирует только TABLE_NAME