Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое блокировка в транзакции?
Блокировка (lock) в транзакции — это механизм управления одновременным доступом к данным, который предотвращает грязное чтение, потерю обновлений и другие аномалии при работе с одной и той же строкой или ресурсом нескольких пользователей одновременно.
Типы блокировок
Shared Lock (S-Lock) — разделённая блокировка для чтения. Несколько транзакций могут одновременно держать S-lock на одной строке, но ни одна не может изменять данные. Используется при SELECT.
Exclusive Lock (X-Lock) — эксклюзивная блокировка для записи. Только одна транзакция может держать X-lock. Ни другие чтения, ни другие записи невозможны. Используется при INSERT, UPDATE, DELETE.
Intent Lock — намеревающаяся блокировка (Intent Shared, Intent Exclusive). Указывает намерение заблокировать строки. Используется для блокировки таблицы.
Уровни блокировок
Row Lock — блокировка отдельной строки. Самая точная и гранулярная.
Page Lock — блокировка страницы (8KB в SQL Server). Промежуточный уровень.
Table Lock — блокировка всей таблицы. Самый грубый уровень, но эффективный для операций с большим объёмом данных.
Уровни изоляции транзакций
READ UNCOMMITTED — грязное чтение разрешено. Низкая блокировка, высокий риск аномалий.
READ COMMITTED — блокировка до конца чтения. Предотвращает грязное чтение, но может быть "phantom read".
REPEATABLE READ — блокировка на время транзакции. Предотвращает грязное чтение и non-repeatable read, но может быть phantom read.
SERIALIZABLE — наивысший уровень изоляции. Транзакции выполняются как бы последовательно. Максимальная безопасность, минимальная производительность.
Практический пример: Deadlock
Дедлок (мёртвая блокировка) происходит, когда две транзакции ждут друг друга:
-- Транзакция 1
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
WAITFOR DELAY 00:00:02; -- Имитация задержки
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
-- Транзакция 2
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 2;
WAITFOR DELAY 00:00:02;
UPDATE accounts SET balance = balance + 100 WHERE id = 1;
COMMIT;
Здесь Транзакция 1 ждёт строку 2, которую держит Транзакция 2, а та в свою очередь ждёт строку 1.
Решение deadlock
-- Использовать тот же порядок обновлений в обеих транзакциях
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
Мониторинг блокировок
-- Посмотреть активные блокировки
SP_WHO2 ACTIVE;
-- Информация о blocks и waiting tasks
SELECT * FROM sys.dm_tran_locks;
-- Убить процесс
KILL process_id;
Проблемы с блокировками
- Deadlock — взаимная блокировка транзакций
- Lock Escalation — переход от row lock к table lock
- Blocking — одна транзакция блокирует другую
- Performance — чем выше уровень изоляции, тем больше блокировок и медленнее система
Блокировки — критическая часть управления одновременностью в базах данных. Правильный их выбор и управление — ключ к стабильной и быстрой работе системы.