«Мертвые» или тупиковые блокировки могут появляться в многопользовательских системах. В качестве примера такой блокировки могут послужить две транзакции, которые блокируют несколько блоков данных. В таком случае может возникнуть ситуация, когда первая транзакция заблокировала один блок, выполнила какие-либо действия с ним и пытается заблокировать другой блок данных. В это же время, вторая транзакция также заблокировала один блок данных, выполнила некоторые операции с ним и пытается заблокировать второй блок данных. Если первая транзакция пытается получить доступ к блоку, который был заблокирован второй транзакцией, а вторая транзакция, в свою очередь, пытается получить доступ к блоку, заблокированному первой транзакцией, то для выполнения обеих транзакций следует дождаться, пока требуемые ими блоки данных будут освобождены.
Но ни первая, ни вторая транзакции не могут освободить заблокированные ими блоки данных, т.к. они еще не завершены. В таком случае возникает «мертвая» или тупиковая блокировка. Более того, возникновение «мертвых» блокировок могут привести к «повисанию в ожидании» все новых и новых транзакций, которым необходимы данные, которые были уже заблокированы транзакциями в тупиковой блокировке.
Если не применять механизмы по обнаружению и снятию возникших «мертвых» блокировок, нормальная работа сервера с транзакциями будет нарушена. В системе по умолчанию установлено бесконечное время ожидания завершения транзакции, что может породить целую сеть транзакций, которые находятся в ожидании освобождения блоков данных. Поэтому, в системе MS SQL Server реализован механизм, который способен разрешить возникшие конфликты блокировки блоков данных транзакциями.
При возникновении тупиковых блокировок, сервер снимает одну из блокировок, которая вызывает конфликт и производит откат всех внесенных изменений, которые, возможно, были произведены в рамках вызвавшей конфликт транзакции. Какую именно блокировку снять, сервер решает на основании соображений минимальной стоимости.
Абсолютной гарантии против возникновения тупиковых блокировок не существует. Хотя в ядро сервера встроен эффективный механизм, позволяющий снять такую блокировку, все же следует принимать во внимание возможность их возникновения и при написании приложений, принимать меры для предупреждения их возникновения. Возникновение «мертвых» блокировок может существенно сказаться на производительности, как приложения, так и сервера баз данных в целом. Это связано с тем, что системе требуется достаточно длительное время для обнаружения таких блокировок, отката транзакций, ее вызвавших и повторного их выполнения после разрешения конфликтной ситуации.
Чтобы свести к минимуму возможность возникновения «мертвых» блокировок, при разработке программного обеспечения для работы с базами данных требует принимать во внимание следующие правила:
• Следует выполнять транзакцию одним пакетом и по возможности свести к минимуму время ее обработки сервером;
• Необходимо соблюдать порядок выполнения действий, чтобы не допускать захвата одних и тех же данных различными транзакциями;
• Не допускать в теле транзакции взаимодействия с пользователем;
• Желательно использовать как можно более низкий уровень изоляции.