Неповторяемое чтение может использовать только зафиксированные версии: конкурент завершился между двумя чтениями. Грязное чтение использует его запись до фиксации. Для различения нужен порядок событий, а не просто наличие двух разных цен.
Почему это важно
Заказ дилера может дважды обратиться к цене одной позиции: при расчёте предложения и перед записью итога. Если приложение ожидает неизменную цену, а режим даёт новый снимок каждому чтению, результаты могут разойтись. Нужно выбрать устойчивый расчёт, блокировку известной строки или явную повторную проверку цены и определить, что сообщить покупателю.
Что подтверждено
Неповторяемое чтение возникает, когда транзакция повторно читает ранее прочитанные данные и обнаруживает изменение или удаление, уже зафиксированное другой транзакцией. Оно отличается от наблюдения чужой ещё не завершённой записи.
Граница применимости: Определение SQL-аномалии по PostgreSQL 18; собственные изменения читающей транзакции исключены из этого сценария.
В PostgreSQL 18 на Read Committed каждый обычный SELECT получает снимок на начало своей команды. Поэтому два SELECT внутри одного BEGIN могут увидеть разные зафиксированные версии одной строки, если конкурент успел изменить её между чтениями.
Граница применимости: PostgreSQL 18, обычные SELECT без явных блокировок; нет собственных изменений целевой строки.
Сеанс А начинает заказ на Read Committed и читает цену 100. Сеанс Б меняет цену той же позиции на 120 и фиксирует транзакцию. А, не завершая свою транзакцию, снова читает эту строку и видит 120. Оба чтения использовали зафиксированные данные; различие возникло из-за нового снимка второй команды.
Граница применимости: Редакторский пример двух сеансов PostgreSQL 18; один ключ позиции, обычные SELECT, Б фиксируется до начала второго SELECT А, А цену не изменяет.
В PostgreSQL 18 Repeatable Read обычные повторные чтения используют снимок, закреплённый первой командой транзакции, не являющейся командой её управления. Чужая более поздняя фиксация новой цены не меняет эту видимую версию; собственные изменения самой транзакции остаются видны.
Граница применимости: PostgreSQL 18, Repeatable Read, обычный SELECT; стабильность чтения не обещает успешную запись поверх конкурентно изменённой строки.
Если PostgreSQL 18 выбрал существующую строку цены через SELECT FOR UPDATE, конкурирующее изменение этой строки ждёт освобождения блокировки. Чтобы связать проверку цены с записью заказа этим способом, обе операции должны оставаться внутри той же транзакции.
Граница применимости: PostgreSQL 18, блокировка выбранной строки до обычного конца транзакции; без отката к более ранней точке сохранения и без обещаний по невыбранным строкам.
Гарантия повторного чтения относится к установленной транзакции. Если расчёт цены и подтверждение заказа проходят в разных транзакциях, Repeatable Read первой из них не закрепляет цену для второй. Сохранение согласованной с покупателем цены требует отдельного правила оформления заказа.
Граница применимости: Редакторский вывод для двух транзакций PostgreSQL 18; не предложение готового механизма хранения коммерческого предложения.
Не путать
Неповторяемое чтение рассматривает изменение ранее прочитанных данных. Фантомное чтение — изменение набора строк, удовлетворяющих повторному условию выборки. В опыте с ценой одной фиксированной позиции проверяют первый сценарий; для фантомов отдельно задают условие и состав выборки.
Что проверить
- В сеансе А начните транзакцию и прочитайте цену позиции по одному известному ключу.
- В сеансе Б измените именно эту цену и выполните COMMIT до следующего чтения А.
- Повторите обычный SELECT в А, не заканчивая транзакцию, и запишите оба значения и фактический уровень изоляции.
- Повторите опыт на Repeatable Read без собственных изменений А; отдельно проверьте возможный конфликт при попытке записи.
- Если выбран способ с SELECT FOR UPDATE, подтвердите ожидание Б и удержание блокировки до завершения заказа в А.
- Проверьте, не разделены ли расчёт предложения и его подтверждение разными запросами с разными транзакциями.
- Определите поведение приложения при изменившейся цене: повторный расчёт, запрос согласия покупателя или правило сохранения согласованной цены.
Первоисточники
PostgreSQL 18 Documentation: Transaction Isolation
PostgreSQL Global Development Group · PostgreSQL 18, Chapter 13.2
Определяет isolation phenomena и фактическое поведение PostgreSQL levels, включая Serializable.
Открыть первоисточникPostgreSQL 18 Documentation: Transactions
PostgreSQL Global Development Group · документация PostgreSQL 18, страница открыта 7 сентября 2026 года
Открыт редактором 7 сентября 2026 года, заголовок документа сверен. Проверить границы BEGIN/COMMIT/ROLLBACK, отдельные транзакции без BEGIN, точки сохранения и оговорку о поведении клиентских библиотек.
Открыть первоисточникPostgreSQL 18 Documentation: Explicit Locking
PostgreSQL Global Development Group · документация PostgreSQL 18, страница открыта 7 сентября 2026 года
Открыт редактором 7 сентября 2026 года, заголовок документа сверен. Проверить блокировки строк SELECT FOR UPDATE, ожидание конкурирующих изменений и срок удержания до конца транзакции.
Открыть первоисточникThe Transaction Model — Turing Award Lecture
Microsoft Research / ACM · Jim Gray, FCRC 1999 lecture slides
Первичный обзор transaction model, ACID, concurrency anomalies, logs и two-phase commit.
Открыть первоисточникPostgreSQL 18 Documentation: Introduction to MVCC
PostgreSQL Global Development Group · PostgreSQL 18, Chapter 13.1
Объясняет multiversion snapshots и границу между MVCC и explicit locking.
Открыть первоисточник