С появлением многопользовательских баз данных встала задача — ограничить одновременное изменение одних и тех же данных. Это привело к появлению различных механизмов блокировок (lock management), которые предотвращают параллельные изменения и помогают поддерживать целостность данных.
Без контроля доступа одновременные операции могут привести к повреждению или потере данных: например, две транзакции одновременно обновляют одну строку, и изменения одной транзакции теряются. Недостаточно строгие блокировки приводят к конкурентным проблемам (race conditions), а избыток — к потерям производительности (deadlocks, contention).
В современных СУБД есть уровни блокировок (row-level, page-level, table-level) и разные режимы (shared, exclusive, update). Программист может управлять этим через настройки изоляции транзакций и явные команды блокировки (например, SELECT ... FOR UPDATE).
Пример кода:
-- Блокировка строки до завершения транзакции BEGIN TRANSACTION; SELECT * FROM users WHERE id = 1 FOR UPDATE; UPDATE users SET name = 'New Name' WHERE id = 1; COMMIT;
Ключевые особенности:
Какова разница между блокировкой на чтение (shared lock) и на запись (exclusive lock)?
Shared lock позволяет нескольким транзакциям читать данные одновременно, но не дает изменять. Exclusive lock разрешает только одной транзакции менять данные, всем остальным запрещен доступ.
Может ли команда SELECT вызвать блокировку?
Обычно SELECT не вызывает блокировок, но если использовать SELECT ... FOR UPDATE или при высоком уровне изоляции (например, SERIALIZABLE), СУБД может заблокировать строки.
Пример кода:
SELECT * FROM products WHERE id = 10 FOR UPDATE;
Блокировки всегда защищают от "потерянных обновлений"?
Нет, если неправильно выбран уровень блокировки или изоляции, можно получить "lost update" — когда изменения одной транзакции теряются из-за другой. Нужно тщательно выбирать механизмы управления конкурентностью.
В отделе аналитики две программы одновременно обновляют статусы заказов. Для ускорения специально выставлен уровень READ UNCOMMITTED, чтобы не блокировать строки. Привело к конфликтам и "потерянным" обновлениям, часть данных повреждена.
Плюсы:
Минусы:
В отделе продаж критические места обернули TRANSACTION + SELECT ... FOR UPDATE. Разграничили операции чтения и обновления на уровне строк.
Плюсы:
Минусы: