О том, как отследить блокировки мы поговорили в прошлый раз. Сегодня я бы хотел поговорить о взаимоблокировках (Deadlocks).
Взаимоблокировка — это когда два процесса конкурируют за 1 ресурс в разном порядке. Пример:
- Задача T1 блокирует ресурс R1 (изображается в виде стрелки от R1 к T1) и запросила блокировку ресурса R2 (изображается в виде стрелки от T1 к R2).
- Задача T2 блокирует ресурс R2 (изображается в виде стрелки от R2 к T2) и запросила блокировку ресурса R1 (изображается в виде стрелки от T2 к R1).
- Так как ни одна из задач не может продолжиться до тех пор, пока не освободится ресурс, а ни один из ресурсов не может быть освобожден до тех пор, пока не продолжится задание, существует состояние взаимоблокировки
Способы отслеживания взаимоблокировко:
1. Performance Monitor, событие SQL Server:Locks — Number of Deadlocks
2. Флаги трассировки 1222 и 1204, не забывайте включить глобально DBCC TRACEON(1222, -1)
3. SQL Server Profiler, событие Locks > Deadlock Graph
4. Extended Events
Как не допускать взаимоблокировок:
1. Использовать нормализованную БД
2. Избегать курсоров
3. Делать транзакции максимально маленькими
4. Уменьшать время блокировок
5. По возможности использовать NOLOCK
6. По возможности использовать минимальный уровень изоляции