Открыть сервис

Пессимистичные блокировки

Пессимистичные блокировки — это механизм управления доступом к данным в системах управления базами данных (СУБД), при котором транзакция блокирует ресурс (строку, таблицу, страницу) на время своего выполнения, предотвращая его изменение или чтение другими транзакциями. Данный подход основан на предположении, что конфликты между транзакциями будут происходить часто, поэтому блокировка накладывается заранее, до выполнения операции. Пессимистичные блокировки противопоставляются оптимистичным блокировкам, где конфликты считаются редкими и проверяются только на этапе фиксации изменений.

Принцип работы

Основная идея пессимистичных блокировок заключается в том, что транзакция, намеревающаяся изменить данные, блокирует их для других транзакций до завершения своей работы. Блокировка снимается только после того, как транзакция завершится (успешно или с откатом). Это гарантирует изоляцию транзакций на уровне сериализуемости, то есть предотвращает такие аномалии, как потерянные обновления, грязное чтение, неповторяющееся чтение и фантомные записи.

Типы блокировок

В зависимости от режима доступа различают несколько типов пессимистичных блокировок:

  • Исключительная блокировка (X-блокировка, exclusive lock) — накладывается на ресурс, который будет изменяться транзакцией. Другие транзакции не могут ни читать, ни изменять этот ресурс до снятия блокировки.
  • Разделяемая блокировка (S-блокировка, shared lock) — накладывается на ресурс, который читается транзакцией. Другие транзакции могут также читать этот ресурс (накладывать разделяемые блокировки), но не могут его изменять.
  • Намеренная блокировка (intent lock) — используется для указания намерения транзакции наложить блокировку на более низком уровне (например, на строке) при блокировке на более высоком уровне (например, на таблице). Это позволяет СУБД эффективно проверять совместимость блокировок.

Гранулярность блокировок

Пессимистичные блокировки могут накладываться на различные уровни гранулярности:

  • Строки — наиболее детальный уровень, позволяющий блокировать только изменяемые записи. Обеспечивает максимальную параллельность, но требует больше ресурсов для управления блокировками.
  • Страницы — блокировка на уровне страницы данных (обычно 4–8 КБ). Менее гранулярна, чем строковая, но снижает накладные расходы.
  • Таблицы — блокировка всей таблицы. Проста в реализации, но резко снижает параллельность, так как другие транзакции не могут работать с таблицей.
  • Базы данных — блокировка всей базы данных. Используется редко, в основном для операций обслуживания.

Реализация в СУБД

Пессимистичные блокировки поддерживаются большинством реляционных СУБД, таких как PostgreSQL, Oracle, Microsoft SQL Server, MySQL (InnoDB) и других. Реализация может различаться в деталях, но общий принцип остаётся неизменным.

Пример на SQL

В PostgreSQL пессимистичная блокировка может быть реализована с помощью команды SELECT ... FOR UPDATE:

``sql BEGIN; SELECT * FROM accounts WHERE id = 1 FOR UPDATE; -- Транзакция блокирует строку с id=1 для других транзакций UPDATE accounts SET balance = balance - 100 WHERE id = 1; COMMIT; ``

В этом примере транзакция накладывает исключительную блокировку на строку с id=1. Другие транзакции, пытающиеся выполнить SELECT ... FOR UPDATE или UPDATE для этой строки, будут ожидать завершения первой транзакции.

Внутренние механизмы

СУБД управляют блокировками с помощью специальных структур данных — таблиц блокировок (lock tables). Каждая блокировка содержит информацию о транзакции-владельце, типе блокировки, гранулярности и ресурсе. Для предотвращения взаимных блокировок (deadlock) СУБД используют механизмы обнаружения и разрешения тупиковых ситуаций, например, выбор транзакции-жертвы и её принудительный откат.

Преимущества и недостатки

Преимущества

  • Гарантированная изоляция — пессимистичные блокировки обеспечивают строгую изоляцию транзакций, предотвращая конфликты на этапе выполнения.
  • Простота реализации — механизм блокировок встроен в СУБД и не требует сложной логики на стороне приложения.
  • Предсказуемость — разработчик точно знает, когда и какие данные будут заблокированы, что упрощает отладку.

Недостатки

  • Снижение параллельности — блокировки могут приводить к длительным ожиданиям, особенно при высокой конкуренции за одни и те же данные.
  • Риск взаимных блокировок (deadlock) — при неправильной последовательности блокировок транзакции могут блокировать друг друга, что приводит к необходимости отката одной из них.
  • Накладные расходы — управление блокировками требует ресурсов процессора и памяти, особенно при большом количестве блокировок.
  • Масштабируемость — в распределённых системах пессимистичные блокировки могут стать узким местом, так как требуют координации между узлами.

Применение

Пессимистичные блокировки используются в сценариях, где конфликты между транзакциями являются частыми и критичными для целостности данных. Типичные примеры:

  • Финансовые системы — обработка платежей, переводов, списаний, где потерянное обновление может привести к расхождению балансов.
  • Системы бронирования — авиабилеты, гостиницы, где одновременное бронирование одного и того же ресурса недопустимо.
  • Инвентаризацияуправление складскими запасами, где важно избежать продажи товара, которого нет в наличии.
  • Редактирование документов — системы коллективной работы, где несколько пользователей могут редактировать один документ, и требуется предотвратить конфликты версий.

Сравнение с оптимистичными блокировками

ХарактеристикаПессимистичные блокировкиОптимистичные блокировки
Предположение о конфликтахЧастыеРедкие
Время блокировкиНа всё время транзакцииТолько на этапе фиксации
ПараллельностьНизкаяВысокая
Риск deadlockВысокийНизкий
Накладные расходыВысокиеНизкие
ПрименимостьВысокая конкуренцияНизкая конкуренция

Критика

Пессимистичные блокировки критикуются за снижение производительности в высоконагруженных системах, особенно при большом количестве одновременных транзакций. В распределённых и микросервисных архитектурах они часто заменяются оптимистичными блокировками или событиями (eventual consistency). Кроме того, неправильное использование пессимистичных блокировок может привести к длительным блокировкам и снижению отзывчивости системы, что требует тщательного проектирования схемы блокировок и мониторинга.

Источники

  • Гектор Гарсиа-Молина, Джеффри Д. Ульман, Дженнифер Уидом. «Системы баз данных. Полный курс».
  • К. Дж. Дейт. «Введение в системы баз данных».
  • Документация PostgreSQL: «Chapter 13. Concurrency Control».
  • Документация MySQL: «InnoDB Locking and Transaction Model».
  • Мартин Клеппман. «Высоконагруженные приложения. Программирование, масштабирование, поддержка».

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →