Ответ
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).