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

Какую аномалию решает уровень изоляции Repeatable Read

1️⃣ Как кратко ответить

Уровень изоляции Repeatable Read решает проблему "неповторяющегося чтения" (non-repeatable read), обеспечивая, что если транзакция читает данные, то другие транзакции не могут изменять эти данные до завершения первой транзакции.

2️⃣ Подробное объяснение темы

Уровень изоляции Repeatable Read — это один из четырех стандартных уровней изоляции транзакций в системах управления базами данных (СУБД), определенных стандартом SQL. Он предназначен для решения проблемы "неповторяющегося чтения", которая возникает, когда одна транзакция читает одни и те же данные несколько раз, но между этими чтениями другая транзакция изменяет эти данные.

Проблема "неповторяющегося чтения"

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

  1. В начале транзакции вы читаете баланс счета, который равен $100.
  2. Пока ваша транзакция еще не завершена, другая транзакция изменяет баланс счета на $150.
  3. Вы снова читаете баланс счета в той же транзакции и видите $150.

Это называется "неповторяющееся чтение", потому что данные, которые вы читали в начале транзакции, изменились до ее завершения.

Как работает Repeatable Read

Уровень изоляции Repeatable Read предотвращает "неповторяющееся чтение" следующим образом:

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

Пример кода

Рассмотрим пример на псевдокоде, чтобы понять, как это работает:

-- Начало транзакции
BEGIN TRANSACTION;
​
-- Чтение баланса счета
SELECT balance FROM accounts WHERE account_id = 1;
​
-- В это время другая транзакция пытается изменить баланс
-- Эта операция будет заблокирована до завершения первой транзакции
UPDATE accounts SET balance = 150 WHERE account_id = 1;
​
-- Повторное чтение баланса счета
SELECT balance FROM accounts WHERE account_id = 1;
​
-- Завершение транзакции
COMMIT;
  • BEGIN TRANSACTION; — начало транзакции. Все операции после этой команды будут частью одной транзакции.
  • SELECT balance FROM accounts WHERE account_id = 1; — чтение баланса счета. Устанавливается блокировка на прочитанные данные.
  • UPDATE accounts SET balance = 150 WHERE account_id = 1; — другая транзакция пытается изменить баланс, но не может этого сделать, пока первая транзакция не завершится.
  • SELECT balance FROM accounts WHERE account_id = 1; — повторное чтение баланса возвращает то же значение, что и первое чтение.
  • COMMIT; — завершение транзакции. Блокировки снимаются, и другие транзакции могут изменять данные.

Применение

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

Тема: Базы данных и SQL
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки