← Назад к вопросам

Какие знаешь блокировки на уровне базы данных?

2.2 Middle🔥 201 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Блокировки на уровне базы данных

В контексте управления параллельным доступом к данным в базах данных, блокировки (lock) являются фундаментальным механизмом обеспечения ACID (Atomicity, Consistency, Isolation, Durability), особенно свойства Isolation (Изолированность). Они предотвращают конфликты при одновременных операциях чтения и записи, обеспечивая корректность данных. В основном, блокировки делятся на два широких класса: блокировки на уровне строк (row-level locks) и блокировки на уровне таблицы (table-level locks). Их реализация и поведение сильно зависят от конкретной СУБД (MySQL, PostgreSQL, Oracle, etc.).

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

1. Блокировки на уровне таблицы (Table-Level Locks)

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

  • Блокировка чтения (SHARED / READ LOCK): Позволяет нескольким транзакциям одновременно читать данные из таблицы, но запрещает любое изменение (INSERT, UPDATE, DELETE) таблицы.
  • Блокировка записи (EXCLUSIVE / WRITE LOCK): Запрещает любым другим транзакциям (включая чтение) доступ к таблице. Используется при операциях изменения структуры таблицы (ALTER TABLE) или массовых обновлениях.

В MySQL, например, при использовании движка MyISAM (который не поддерживает транзакции), применяются именно такие автоматические блокировки всей таблицы для каждой операции записи.

2. Блокировки на уровне строк (Row-Level Locks)

Это более тонкий механизм, который блокирует только конкретные строки, участвующие в транзакции. Он обеспечивает лучшую параллельность, но требует больше ресурсов и сложного управления (например, предотвращения deadlock — взаимной блокировки). Поддерживается движками, работающими с транзакциями (например, InnoDB в MySQL).

  • Блокировка записи строки (Exclusive Row Lock / X Lock): Транзакция, изменяющая строку (UPDATE, DELETE), устанавливает на нее исключительную блокировку. Никакая другая транзакция не может читать (в режиме, требующем блокировки) или изменять эту строку до завершения первой.
  • Блокировка чтения строки (Shared Row Lock / S Lock): Транзакция, которая просто читает строку в определенном контексте (например, с использованием SELECT ... FOR SHARE в MySQL 8+ или LOCK IN SHARE MODE в более ранних версиях), устанавливает совместную блокировку. Другие транзакции также могут установить совместную блокировку на эту строку для чтения, но не могут установить исключительную для изменения.
-- Пример в MySQL (InnoDB) с блокировкой строк для чтения (старый синтаксис)
START TRANSACTION;
SELECT * FROM accounts WHERE user_id = 1 FOR UPDATE; -- Устанавливает EXCLUSIVE (X) lock на строку(и)
-- ... выполнение операций UPDATE/DELETE над этой строкой ...
COMMIT;

Специализированные блокировки и концепции

Помимо базовых, существуют более специфичные виды блокировок и связанные понятия:

  • Intent Locks (Блокировки намерения): Используются в системах с многоуровневой блокировкой (например, таблица -> строки). Блокировка намерения на таблицу указывает, что транзакция планирует заблокировать некоторые строки в этой таблице. Это помогает эффективно обнаруживать потенциальные конфликты на уровне таблицы без проверки каждой строки. Различают Intention Shared (IS) и Intention Exclusive (IX).
  • Gap Locks (Блокировки интервала): Особенность InnoDB. Блокируется не существующая строка, а интервал между существующими значениями индекса. Это предотвращает INSERT операций в этот интервал, защищая от так называемых phantom reads (фантомных чтений) в определенных уровнях изоляции транзакций (например, REPEATABLE READ).
  • Deadlock (Взаимная блокировка): Ситуация, когда две или более транзакции взаимно блокируют друг друга, ожидая освобождения ресурса, захваченного другой транзакцией. СУБД обычно имеют механизм deadlock detection, который прерывает одну из транзакций, чтобы разрешить ситуацию.
-- Пример, иллюстрирующий потенциальный deadlock
-- Транзакция 1:
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1; -- X lock на строку id=1
UPDATE accounts SET balance = balance + 100 WHERE id = 2; -- Ожидает X lock на строку id=2

-- Транзакция 2 (выполняется параллельно):
START TRANSACTION;
UPDATE accounts SET balance = balance - 50 WHERE id = 2; -- X lock на строку id=2
UPDATE accounts SET balance = balance + 50 WHERE id = 1; -- Ожидает X lock на строку id=1 -> DEADLOCK

Уровни изоляции транзакций и блокировки

Тип и количество используемых блокировок напрямую зависят от установленного Level of Isolation.

  • READ UNCOMMITTED: Блокировки, как правило, не используются для операций чтения (возможны dirty reads).
  • READ COMMITTED: Для предотвращения dirty reads могут использоваться кратковременные блокировки строк.
  • REPEATABLE READ (стандарт для InnoDB): Используются блокировки строк (и часто gap locks) для обеспечения того, что повторное чтение даст тот же результат.
  • SERIALIZABLE: Самый строгий уровень. Часто реализуется через агрессивное использование блокировок чтения (shared locks), что делает выполнение транзакций почти последовательным.

Вывод: Понимание системы блокировок конкретной СУБД критически важно для разработчика Backend. Неправильное использование (например, слишком долгие транзакции с блокировками на популярных строках) может привести к серьезным проблемам с производительностью (contention) и взаимным блокировкам. Правильный выбор уровня изоляции, минимальная длительность транзакций и аккуратное использование явных блокировок (FOR UPDATE, FOR SHARE) — ключевые навыки для построения надежных и эффективных приложений.