Что такое блокировка (Lock) в контексте баз данных?

«Что такое блокировка (Lock) в контексте баз данных?» — вопрос из категории Базы данных, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Блокировка (Lock) в базах данных — это механизм управления параллельным доступом к данным, который предотвращает конфликты при одновременных операциях чтения и записи несколькими транзакциями. Его основная цель — обеспечить согласованность данных (ACID-свойство изоляции).

Основные типы блокировок в СУБД:

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

Уровни изоляции и блокировки: Поведение блокировок напрямую зависит от уровня изоляции транзакции. Например, при уровне READ COMMITTED в PostgreSQL разделяемые блокировки снимаются сразу после чтения строки, а при REPEATABLE READ — удерживаются до конца транзакции.

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

-- Начало транзакции
BEGIN;

-- Явная установка эксклюзивной блокировки на строку для обновления.
-- Это пессимистичный подход, предотвращающий "lost update".
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;

-- Выполнение операции с заблокированной строкой
UPDATE accounts SET balance = balance - 100 WHERE id = 1;

COMMIT;

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

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

На практике важно проектировать транзакции так, чтобы они были короткими, захватывали блокировки в предсказуемом порядке и использовали подходящий уровень изоляции, чтобы минимизировать негативное влияние на параллелизм.