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

Разделяемая блокировка

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

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

Разделяемая блокировка реализует концепцию «читатели не блокируют читателей, но блокируют писателей». Когда транзакция запрашивает разделяемую блокировку на ресурс, система проверяет, не удерживается ли на этом ресурсе исключительная блокировка (X-lock) другой транзакцией. Если исключительная блокировка отсутствует, запрос удовлетворяется, и транзакция получает доступ к данным для чтения. Если исключительная блокировка уже установлена, транзакция, запрашивающая разделяемую блокировку, переходит в состояние ожидания до её освобождения.

Несколько транзакций могут одновременно удерживать разделяемые блокировки на одном и том же ресурсе. Это позволяет реализовать высокую степень параллелизма при операциях чтения, что критически важно для систем с интенсивным чтением данных, таких как веб-приложения, аналитические системы и отчётные модули.

Отличие от исключительной блокировки

Основное различие между разделяемой и исключительной блокировками заключается в уровне доступа, который они предоставляют:

  • Разделяемая блокировка (S-lock): разрешает только чтение данных. Другие транзакции также могут получить разделяемую блокировку на тот же ресурс, но не могут получить исключительную блокировку.
  • Исключительная блокировка (X-lock): разрешает как чтение, так и запись (модификацию, удаление, вставку) данных. Только одна транзакция может удерживать исключительную блокировку на конкретный ресурс в любой момент времени. Никакая другая транзакция не может получить ни разделяемую, ни исключительную блокировку на этот ресурс, пока X-lock удерживается.

Это различие лежит в основе механизма управления параллельным доступом, известного как двухфазная блокировка (2PL).

Применение в СУБД

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

  • Read Uncommitted (чтение неподтверждённых данных): разделяемые блокировки могут не устанавливаться, что допускает «грязное» чтение.
  • Read Committed (чтение подтверждённых данных): разделяемые блокировки обычно устанавливаются на время выполнения запроса SELECT, но освобождаются сразу после его завершения. Это предотвращает «грязное» чтение, но не гарантирует неповторяющееся чтение.
  • Repeatable Read (повторяемое чтение): разделяемые блокировки удерживаются до конца транзакции, что предотвращает неповторяющееся чтение, но может приводить к взаимоблокировкам (deadlocks).
  • Serializable (сериализуемый): разделяемые блокировки могут использоваться в сочетании с другими механизмами (например, блокировками диапазонов) для обеспечения полной изоляции транзакций.

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

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

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

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

Недостатки

  • Снижение параллелизма при записи: если одна транзакция удерживает разделяемую блокировку, другая транзакция не может получить исключительную блокировку для записи. Это может приводить к задержкам при операциях обновления данных.
  • Риск взаимоблокировок (deadlocks): когда две или более транзакции удерживают разделяемые блокировки и одновременно запрашивают исключительные блокировки на ресурсы, заблокированные друг другом, возникает взаимоблокировка. СУБД обычно обнаруживают такие ситуации и разрешают их, откатывая одну из транзакций.
  • Невозможность гарантировать неповторяющееся чтение на низких уровнях изоляции: при использовании уровня Read Committed разделяемые блокировки освобождаются сразу после чтения, что может привести к тому, что повторное чтение тех же данных в рамках одной транзакции покажет другой результат.

Примеры использования

Разделяемые блокировки применяются во всех системах, где требуется одновременный доступ к данным для чтения. Примеры:

  • Веб-приложения: при отображении страницы с данными из базы (например, каталог товаров, список пользователей) каждый запрос к базе данных устанавливает разделяемую блокировку на читаемые строки.
  • Отчётные системы: при формировании отчётов, которые требуют чтения больших объёмов данных, разделяемые блокировки позволяют нескольким отчётам выполняться параллельно, не мешая друг другу.
  • Системы управления контентом (CMS): при одновременном просмотре статей несколькими пользователями разделяемые блокировки обеспечивают согласованность данных.

Альтернативы

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

  • Многоверсионное управление параллельным доступом (MVCC): позволяет читателям видеть «снимок» данных на момент начала транзакции, не блокируя писателей. Это снижает количество блокировок и повышает производительность.
  • Оптимистическая блокировка: предполагает, что конфликты редки, и проверяет их только на этапе фиксации транзакции. При обнаружении конфликта транзакция откатывается и повторяется.
  • Блокировки на уровне таблиц или страниц: в некоторых СУБД (например, в старых версиях MySQL с MyISAM) разделяемые блокировки могут устанавливаться на целую таблицу, что снижает параллелизм, но упрощает реализацию.

Интересные факты

  • Термин «разделяемая блокировка» (shared lock) был введён в рамках теории управления параллельным доступом, разработанной в 1970-х годах, в частности, в работах Джима Грея и других исследователей.
  • В некоторых СУБД, например в Oracle Database, разделяемые блокировки не используются для операций SELECT в стандартном режиме, так как Oracle полагается на MVCC. Однако они могут применяться при явном указании блокировки (например, с помощью оператора SELECT ... FOR SHARE).
  • В Microsoft SQL Server разделяемые блокировки могут быть повышены до исключительных, если транзакция, удерживающая S-lock, пытается выполнить операцию записи. Это называется «повышением блокировки» (lock escalation).

Источники

  • Gray, J., & Reuter, A. (1993). Transaction Processing: Concepts and Techniques. Morgan Kaufmann.
  • Silberschatz, A., Korth, H. F., & Sudarshan, S. (2010). Database System Concepts (6th ed.). McGraw-Hill.
  • Date, C. J. (2003). An Introduction to Database Systems (8th ed.). Addison-Wesley.
  • Документация PostgreSQL: «Управление блокировками».

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

На главную BFOmetr →