Ответ
Repeatable Read гарантирует, что данные, прочитанные в рамках транзакции, остаются неизменными до её завершения, предотвращая аномалии неповторяющегося чтения (non-repeatable read). Это оптимально для сценария, где каждая транзакция работает со своей уникальной записью (например, WHERE user_id = ?).
Почему это работает:
- Система блокирует только строки, к которым происходит обращение (поиск по индексу), а не всю таблицу.
- Транзакции, изменяющие разные строки, не конфликтуют.
- Сохраняется высокая производительность при параллельных операциях
read-modify-writeв пределах одной записи.
Пример (псевдокод):
-- Транзакция пользователя A (ID=1)
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT balance FROM accounts WHERE user_id = 1; -- Читает и блокирует строку для user_id=1
-- ... логика на основе balance ...
UPDATE accounts SET balance = 150 WHERE user_id = 1;
COMMIT;
-- Транзакция пользователя B (ID=2) выполняется параллельно
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT balance FROM accounts WHERE user_id = 2; -- Блокирует свою строку, не конфликтует с первой
UPDATE accounts SET balance = 200 WHERE user_id = 2;
COMMIT;
Ограничения:
- Не защищает от фантомного чтения (появление новых строк, соответствующих условию WHERE).
- Риск взаимоблокировки (deadlock) при непоследовательном порядке обновления строк разными транзакциями.