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

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

Простой способ предотвратить это — заблокировать файл всякий раз, когда запись изменяется любым пользователем, чтобы никакой другой пользователь не мог сохранить данные. Это предотвращает неправильную запись записей, но позволяет обрабатывать только одну запись за один раз, блокируя других пользователей, которым необходимо одновременно редактировать записи.

Чтобы разрешить нескольким пользователям одновременно редактировать таблицу базы данных, а также предотвращать несоответствия, созданные неограниченным доступом, можно восстановить одну запись при её извлечении для редактирования или обновления. Любому, кто пытается получить одну и ту же запись для редактирования, запрещается доступ на запись из-за блокировки (хотя, в зависимости от реализации, они могут просматривать запись, не редактируя её). Когда запись сохранена или изменения отменены, блокировка будет отпущена. Записи могут быть не сохранены, чтобы перезаписывать другие изменения, сохраняя целостность данных.

В теории управления базами данных блокировка используется для реализации изоляции между несколькими пользователями базы данных. Это «I» в сокращенном ACID.

Подробное и авторитетное описание блокировки было написано Джимом Грей.

Классификации блокировок По области действия блокировки классифицируются на строчные, гранулярные и предикатные. По строгости блокировки разделяются на совместные () и исключительные (эксклюзивные, ). По логике реализации блокировки делятся на оптимистические и пессимистические

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

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

Предикатная блокировка действует на область, ограниченную предикатом. Обычно это блокировка по диапазону ключей. При такой блокировке для ключа или индекса указывается значение или диапазон значений, на которые распространяется блокировка. Такая блокировка (а также блокировка всей таблицы), помимо прочего, защищает от чтения фантомов и обеспечивает уровень изоляции транзакции Serializable.

Введение гранулированных (подмножеств) замков создает возможность возникновения ситуации, называемой «мертвая блокировка» (взаимоблокировка). Тупик возможен, когда используется инкрементная блокировка (блокировка одного объекта, затем блокировка одного или нескольких дополнительных объектов). Чтобы проиллюстрировать, если два клиента банка попросили двух клерков получить информацию об учётной записи, чтобы они могли перевести некоторые деньги на другие счета, эти два счета были бы по существу заблокированы. Затем, если клиенты сказали своим клеркам, что деньги должны были быть переведены на счета друг друга, клерки будут искать другие счета, но находят их «активными» и ждут их возвращения. Не зная, два клерка ждут друг друга, и ни один из них не может завершить свою транзакцию, пока другой не сдастся и не вернет счет. Для избежания таких проблем используются различные методы.

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

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

Исключительные блокировки Исключительная блокировка накладывается транзакцией на объект в случае, если выполняемая ей операция изменяет данные. Только одна транзакция может выполнять подобную операцию над объектом, если на него наложена исключительная блокировка. Блокировка не может быть наложена на объект, если на него уже наложена совместная блокировка.

Исключительные блокировки, как следует из названия, принадлежат исключительно одному лицу, обычно для целей записи в запись. Если схема блокировки была представлена списком, список держателей будет содержать только одну запись. Поскольку этот тип блокировки эффективно блокирует любую другую сущность, которая требует обработки блокировки, необходимо соблюдать осторожность: Обеспечить фиксацию замка нужно в как можно более короткий промежуток времени; Не удерживать блокировку в системных или функциональных вызовах, когда объект больше не работает на процессоре — это может привести к взаимоблокировке; Убедитесь, что если объект неожиданно завершает работу по какой-либо причине, блокировка будет освобождена. Номера держателей блокировки (иначе называемые «держателями») могут храниться в списке, обслуживаемом циклически или в очереди FIFO. Это гарантирует, что любой возможный держатель будет иметь равную возможность получить блокировку и не будет заблокирован. Чтобы ещё больше ускорить процесс, если сущность в ожидании блокировки, субъект уведомляется о гранте — это увеличит производительность, вместо того, чтобы обнаружить его на каком-то системном тайм-ауте, управляемом пробуждением.

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

Общие блокировки отличаются от «эксклюзивных» блокировок тем, что список держателей может содержать несколько записей. Общие блокировки позволяют всем держателям читать содержимое записи, зная, что запись не может быть изменена до тех пор, пока блокировка не будет освобождена всеми держателями. Исключительные блокировки не могут быть получены, когда запись уже заблокирована (исключительно или совместно) другим объектом.

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

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

Оптимистическая блокировка не ограничивает модификацию обрабатываемых данных сторонними сессиями, однако перед началом предполагаемой модификации запрашивает значение некоторого выделенного атрибута каждой из строк данных (обычно используется наименование VERSION и целочисленный тип с начальным значением 0). Перед записью модификаций в базу данных перепроверяется значение выделенного атрибута, и если оно изменилось, то транзакция откатывается или применяются различные схемы разрешения коллизий. Если значение выделенного атрибута не изменилось — производится фиксация модификаций с одновременным изменением значения выделенного атрибута (например, инкрементом) для сигнализации другим сессиям о том, что данные изменились.

Примечания

Категория:Управление конкурентными потоками Категория:Обработка транзакций Категория:СУБД