Введение
Решение для обеспечения конкурентного доступа к базе данных
Блокировка записей — это метод предотвращения одновременного доступа к данным в базе данных, чтобы избежать несогласованных результатов. Классический пример демонстрируется двумя банковскими служащими, пытающимися обновить один и тот же банковский счет для двух разных операций. Служащий 1 и служащий 2 получают (то есть копируют) запись о счете. Служащий 1 применяет и сохраняет операцию. Служащий 2 применяет другую операцию к своей сохраненной копии и сохраняет результат, основанный на исходной записи и его изменениях, перезаписывая операцию, внесенную служащим 1. Запись больше не отражает первую операцию, как будто она никогда не выполнялась. Простой способ предотвратить это — заблокировать файл при изменении записи любым пользователем, чтобы другие пользователи не могли сохранить данные. Это предотвращает неправильную перезапись записей, но позволяет обрабатывать только одну запись за раз, блокируя других пользователей, которым необходимо одновременно редактировать записи. Чтобы разрешить нескольким пользователям редактировать таблицу базы данных одновременно и предотвратить несоответствия, вызванные неограниченным доступом, отдельная запись может быть заблокирована при извлечении для редактирования или обновления. Любой, кто пытается получить ту же запись для редактирования, будет лишен прав записи из-за блокировки (хотя, в зависимости от реализации, они могут просматривать запись без ее редактирования). После сохранения записи или отмены изменений блокировка снимается. Записи никогда не могут быть сохранены таким образом, чтобы перезаписать другие изменения, обеспечивая целостность данных. В теории управления базами данных блокировка используется для реализации изоляции между несколькими пользователями базы данных. Это "И" в аббревиатуре ACID. Подробное и авторитетное описание блокировки было написано Джимом Греем.
Гранулярность замков
Если банковские клерки (согласно приведенной выше иллюстрации) обслуживают двух клиентов, но их счета содержатся в одной книге, то вся книга или одна или несколько таблиц базы данных должны быть предоставлены к редактированию клеркам, чтобы каждый мог завершить транзакцию по очереди (блокировка файла). Хотя этот метод безопасен, он может приводить к неоправданному ожиданию. Если клерки могут извлечь одну страницу из книги, содержащую счет текущего клиента (плюс несколько других счетов), то можно одновременно обслуживать нескольких клиентов, при условии, что счет каждого клиента находится на отдельной странице от других. Если у двух клиентов счета на одной странице, то обслуживать можно только одного из них за раз. Это аналогично блокировке на уровне страницы в базе данных. Более высокая степень гранулярности достигается, если каждый отдельный счет может быть взят клерком. Это позволит обслуживать любого клиента, не дожидаясь другого, который обращается к другому счету. Это аналогично блокировке на уровне записи и обычно является максимальной степенью гранулярности блокировки в системе управления базами данных. В базе данных SQL запись обычно называется "строкой". Введение гранулярных (подмножеств) блокировок создает возможность возникновения ситуации, называемой взаимоблокировкой (дедлоком). Взаимоблокировка возможна при использовании инкрементной блокировки (блокировка одного объекта, а затем одного или нескольких дополнительных объектов). Например, если два клиента банка попросят двух клерков получить информацию об их счетах для перевода денег на другие счета, эти два счета фактически будут заблокированы. Затем, если клиенты попросят своих клерков перевести деньги на счета друг друга, клерки будут искать другие счета, но обнаружат, что они "заняты" и будут ждать их освобождения. Не зная об этом, два клерка будут ждать друг друга, и ни один из них не сможет завершить свою транзакцию, пока другой не откажется от блокировки и не освободит счет. Для предотвращения таких проблем используются различные методы.
Общие замки
Общие блокировки отличаются от эксклюзивных тем, что список держателей может содержать несколько элементов. Общие блокировки позволяют всем держателям читать содержимое записи, зная, что запись не может быть изменена, пока все держатели не освободят блокировку. Эксклюзивные блокировки не могут быть получены, если запись уже заблокирована (эксклюзивно или совместно) другим субъектом. Если запросы на блокировку для одного и того же субъекта находятся в очереди, то после предоставления общей блокировки любые ожидающие общие блокировки также могут быть предоставлены. Если в очереди далее находится запрос на эксклюзивную блокировку, она должна ждать, пока все общие блокировки не будут освобождены. Как и в случае с эксклюзивными блокировками, общие блокировки следует удерживать как можно меньшее время.