lesson ── postgres-labs ── ~22 мин ── 5 шагов
Посмотри на снимок в SQL и убедись, что на Repeatable Read он заморожен: чужой коммит, случившийся после старта транзакции, в неё не просочится. Перед каждым чтением предсказывай результат.
интерактивный sandbox
Поднимется контейнер postgreslab/postgres-base с PostgreSQL 17 и psql. В браузере откроется терминал, база lab уже настроена. Каждый шаг проверяется автоматически. Сеть air-gapped, наружу контейнер не ходит.
stack ── PostgreSQL 17 · psql · 1 GB RAM · air-gapped · самоуничтожается через 45 мин простоя
Во вкладке A посмотри текущий снимок и разбери его на три части xmin:xmax:список.
SELECT pg_current_snapshot();
Формат - два числа через двоеточие и список активных xid.
✓ Снимок - это числа, а не копия данных.
Открой транзакцию на Repeatable Read и прочитай число билетов. Запомни его - снимок взялся прямо сейчас и держится до конца транзакции.
BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT count(*) FROM tickets;
На Repeatable Read снимок один на всю транзакцию.
✓ Транзакция A открыта с замороженным снимком.
Перейди во вкладку B и добавь новый билет, сразу зафиксировав.
INSERT INTO tickets VALUES ('9999999999999', '000001', 1, 'NEW');COMMIT;
✓ B вставила билет и зафиксировала - билетов стало 501.
Вернись во вкладку A и снова прочитай число билетов. Предскажи: увидишь ли вставку сессии B? В своей транзакции ты по-прежнему видишь старое число (500): снимок заморожен. А свежее соединение - вроде этой проверки - уже видит 501.
SELECT count(*) FROM tickets;
Снимок A взялся до коммита B, поэтому вставка B в него не попала.
✓ Свежее соединение видит 501, а замороженная транзакция A - всё ещё 500.
Заверши транзакцию A. Теперь её снимок сброшен, и повторное чтение увидит вставку сессии B.
COMMIT;
SELECT count(*) FROM tickets;
✓ Транзакция A закрыта - больше нет замороженных снимков.
Снимок - это числа xmin:xmax:список, а не копия. На Repeatable Read он берётся один раз на транзакцию и держится до конца: чужой коммит после старта в транзакцию не просачивается, хотя свежее соединение его видит.
команды
SELECT pg_current_snapshot();снимок в формате xmin:xmax:списокBEGIN ISOLATION LEVEL REPEATABLE READ;заморозить снимок на транзакциюконцепции