зеркало из
https://github.com/iharh/notes.git
synced 2025-10-29 12:46:06 +02:00
26 строки
3.4 KiB
Plaintext
26 строки
3.4 KiB
Plaintext
*****************************************************************************************************
|
|
В PostgreSQL есть мощный механизм блокировок, который как раз может помочь избежать таких ситуаций на уровне базы данных, упростив разработку приложения.
|
|
|
|
Выражение SELECT FOR UPDATE, в отличии от обычного SELECT устанавливает блокировку на уровне строк (row-level lock), что и позволяет безопасно поменять данные,
|
|
избежав конфликтных ситуаций. Когда мы используем SELECT FOR UPDATE, блокировка не дает изменить или удалить выбранные строки другим транзакциям, до завершения текущей транзакции.
|
|
|
|
Если продолжать аналогию с системой бронирования номеров в отеле, то можно привести вот такой пример запроса:
|
|
|
|
BEGIN ;
|
|
|
|
SELECT * FROM rooms WHERE room._number = '10' and status = 'available' FOR UPDATE;
|
|
|
|
Здесь мы явно открываем транзакцию (BEGIN) и из таблицы с номерами отеля (rooms) , выбираем комнату с номером 10 и статусом свободна (available).
|
|
|
|
Таким образом мы можем быть уверены, что пока пользователь выбирает и оплачивает номер, другой не успеет его забронировать, так как запись будет заблокирована до конца транзакции.
|
|
|
|
Чтобы избежать ситуаций когда SELECT FOR UPDATE не может получить блокировку, так как строка заблокирована другой транзакцией,
|
|
в результате чего происходят сильные задержки в транзакции или взаимоблокировки, существует опция NOWAIT.
|
|
Эта опция позволяет приложению избежать конфликтов блокировок в реальном времени, вместо того чтобы ждать когда освободиться необходимая строка.
|
|
|
|
Существует еще одна полезная опция в контексте выражения SELECT FOR UPDATE, называется она SKIP LOCKED.
|
|
Суть ее состоит в том, что она позволяет избежать строк, которые уже заблокированы другой транзакцией.
|
|
Т.е. в примере, приведенном выше, если бы вторая транзакция искала свободные номера, то она бы не увидела в своем результате комнату с номером 10.
|
|
Опять же, эта опция позволяет повысить конкурентность выполнения транзакций и избежать ненужных ожиданий на блокировках.
|
|
*****************************************************************************************************
|