--- aliases: - повторяющееся чтение tags: - зрелость/🌱 date: - - 2024-06-19 zero-link: - "[[00 Базы Данных]]" parents: - "[[Уровни изоляций транзакций БД]]" linked: prev: "[[Read committed]]" next: "[[Serializable]]" --- **Repeatable read (повторяющееся чтение).** Уровень, при котором читающая транзакция «не видит» изменения данных, которые были ею ранее прочитаны. При этом никакая другая транзакция не может изменять данные, читаемые текущей транзакцией, пока та не окончена. ^38dd4b ![](Pasted%20image%2020240619201149.png) Первая транзакция началась. Считала баланс первого пользователя. Обновила его, но не зафиксировала изменения. Началась вторая транзакция. Она также считала баланс первого пользователя, обновила его, но тоже не зафиксировала свои изменения. А теперь правильной окажется та транзакция, которая зафиксирует свои изменения первой. Первая транзакция выполнила коммит первой, поэтому коммит второй транзакции завершился ошибкой. Но если вторая транзакция не изменяла данные, а добавляла новые строчки, то исключения не было бы. Также проблем не будет, если мы обновим баланс второго пользователя. Но возникает закономерный вопрос: что делать с ошибкой, ведь мы хотели выполнить транзакцию, которая свалилась с исключением. Самое простое, что можно сделать — это повторить выполнение второй транзакции с новыми данными. Если исключение возникнет опять, то повторить снова. **Реализация:** - [Блокировки](Блокировки.md). Чтение не блокирует запись, а запись не блокирует чтение. - [MVCC](MVCC.md) **Особенности:** - В [PostgreSQL](00%20PostgreSQL.md) на уровне `REPEATABLE_READ` также предотвращены фантомные чтения. **Проблемы:** - [Фантомное чтение](Фантомное%20чтение.md) **Когда использовать:** Вставка новых записей в параллельных транзакциях не влияет на текущую транзакцию.