Что такое блокировка (lock) в контексте транзакций СУБД?

«Что такое блокировка (lock) в контексте транзакций СУБД?» — вопрос из категории SQL и базы данных, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Основные типы блокировок:

  1. Разделяемая блокировка (Shared Lock, S): Ставится при операциях чтения. Несколько транзакций могут одновременно удерживать S-блокировки на одних и тех же данных, но ни одна из них не сможет поставить эксклюзивную блокировку, пока существуют S-блокировки.
  2. Эксклюзивная блокировка (Exclusive Lock, X): Ставится при операциях изменения (INSERT, UPDATE, DELETE). Только одна транзакция может удерживать X-блокировку на данных. Пока она действует, другие транзакции не могут получить ни S-, ни X-блокировку на эти данные.

Как это работает на практике (пример в T-SQL):

-- Транзакция 1 (в сессии A)
BEGIN TRANSACTION;
-- СУБД автоматически ставит X-блокировку на обновляемую строку
UPDATE Orders SET Status = 'Shipped' WHERE OrderId = 1234;
-- Пока транзакция не завершена (COMMIT/ROLLBACK), блокировка удерживается.

-- Транзакция 2 (в сессии B, выполняется параллельно)
BEGIN TRANSACTION;
-- Этот запрос будет ЖДАТЬ (заблокирован), пока транзакция 1 не снимет X-блокировку.
SELECT * FROM Orders WHERE OrderId = 1234; -- Ожидание...
-- Если ожидание превысит таймаут, произойдет ошибка.
COMMIT;

Явное управление блокировками (на примере SQL Server):

-- Использование подсказок блокировок (lock hints)
BEGIN TRANSACTION;
-- UPDLOCK: Ставит U-блокировку (Update lock) для предотвращения deadlock'ов при последующем обновлении.
SELECT * FROM Products WITH (UPDLOCK) WHERE ProductId = 10;

-- ... какая-то бизнес-логика ...

-- Теперь обновление безопасно, U-блокировка преобразуется в X-блокировку.
UPDATE Products SET Stock = Stock - 1 WHERE ProductId = 10;
COMMIT TRANSACTION;

Проблемы, связанные с блокировками:

  • Взаимоблокировка (Deadlock): Когда две и более транзакций взаимно ожидают снятия блокировок друг с другом. СУБД обнаруживает deadlock и принудительно откатывает одну из транзакций (жертву deadlock'а).
  • Блокировки (Contention): Длительные или частые блокировки на популярных данных могут стать "бутылочным горлышком" и резко снизить пропускную способность системы.

Управление: Проблемы решаются правильным проектированием схемы БД, написанием эффективных запросов (быстрых транзакций), выбором подходящего уровня изоляции транзакций (например, READ COMMITTED, REPEATABLE READ, SERIALIZABLE) и, в некоторых случаях, использованием оптимистичных блокировок (например, через поля версий).