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

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

Ответ

Shared Lock (S-Lock) — это тип пессимистической блокировки в СУБД, которая позволяет нескольким транзакциям одновременно читать одну и ту же запись, но запрещает любой транзакции изменять её.

Принцип совместимости блокировок: Текущая блокировка Запрашиваемая Shared Lock Exclusive Lock
Shared Lock ✅ Разрешено ❌ Запрещено
Exclusive Lock ❌ Запрещено ❌ Запрещено

Для чего используется:

  • Гарантия согласованности чтения — предотвращает чтение незафиксированных данных (грязное чтение, Dirty Read).
  • Позволяет реализовать уровень изоляции READ COMMITTED и выше.

Пример SQL (PostgreSQL/MySQL):

-- Явный запрос разделяемой блокировки на строку
BEGIN TRANSACTION;
SELECT * FROM accounts WHERE id = 123 FOR SHARE; -- или LOCK IN SHARE MODE в MySQL
-- Другие транзакции также могут выполнить SELECT ... FOR SHARE,
-- но SELECT ... FOR UPDATE или UPDATE/INSERT/DELETE будут ждать.
COMMIT;

Пример в JPA (Hibernate):

// Явная установка пессимистической блокировки на чтение
Account account = entityManager.find(Account.class, 123L, LockModeType.PESSIMISTIC_READ);
// Или через запрос
TypedQuery<Account> q = entityManager.createQuery("SELECT a FROM Account a WHERE a.id = :id", Account.class);
q.setParameter("id", 123L);
q.setLockMode(LockModeType.PESSIMISTIC_READ);
Account account = q.getSingleResult();

Важно: Разделяемые блокировки могут привести к взаимоблокировке (deadlock), если две транзакции попытаются сначала захватить S-Lock, а затем обновить данные (запросить X-Lock).