Files
huncode 323d80b188
Build and deploy / deploy (push) Successful in 14s
revise January 2021 transaction articles
2026-07-31 12:13:15 +03:00

167 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Январь 2021 — тройное ревью автономной партии P35 «Границы транзакции PostgreSQL»
Статус: **автономный пакет принят в выпусковой набор после трёх проходов**.
В объектах revision нет полей `date` и `author`: публикационный слой должен
сохранить метаданные базового архива. Пакет не менял registry,
`articles.json`, README, очередь, package configuration или Git.
Проверенные revision:
- `editorial-2021-01-practice-transactions`;
- `editorial-2021-01-mechanism-transactions`;
- `editorial-2021-01-field-transactions`.
Модуль экспортирует ровно три revision. Режим `--print-revisions` пишет только
JSON. Режим `--verify-fixture` запускает только детерминированную in-memory
модель; он не открывает PostgreSQL, не выполняет SQL, не создаёт настоящий lock
и не измеряет contention.
## Проход 1. Факты, историческая рамка и механизм — пройдено
| Утверждение или решение | Первичный / официальный источник | Зафиксированная граница |
| --- | --- | --- |
| В январе 2021 PostgreSQL 13 уже имел минорный релиз 13.1 от 12 ноября 2020 года | [PostgreSQL 13.1 release](https://www.postgresql.org/about/news/postgresql-131-125-1110-1015-9620-and-9524-released-2111/) | Тексты ссылаются именно на документацию ветки 13 и не переносят её формулировки на неизвестную версию сервера или driver. |
| `Read Committed` — default; его snapshot начинается на каждом statement. PostgreSQL `Read Uncommitted` ведёт себя как `Read Committed` | [PostgreSQL 13: Transaction Isolation](https://www.postgresql.org/docs/13/transaction-iso.html) | Два `SELECT` одной transaction могут увидеть разные committed state; это не доказательство cross-row invariant. |
| PostgreSQL `Repeatable Read` не допускает phantom reads, но не исключает serialization anomaly; `Serializable` сохраняет только outcomes, эквивалентные serial order, и требует retry отменённой transaction | [PostgreSQL 13: Transaction Isolation](https://www.postgresql.org/docs/13/transaction-iso.html) | Пакет не объявляет `Repeatable Read` «почти Serializable» и не называет Serializable универсально лучшим уровнем. |
| `SELECT ... FOR UPDATE` защищает только returned rows от конфликтующих writers и lockers до конца transaction; разные order нескольких locks создают риск deadlock | [PostgreSQL 13: Explicit Locking](https://www.postgresql.org/docs/13/explicit-locking.html) | Каждый SQL-пример показывает predicate и `ORDER BY`; тексты требуют общий scope и order от всех writers. |
| Для non-serializable path PostgreSQL отделяет Serializable-подход от explicit blocking locks; `SELECT FOR UPDATE` не создаёт вечный запрет после завершения transaction | [PostgreSQL 13: Application-Level Consistency](https://www.postgresql.org/docs/13/applevel-consistency.html) | Пакет не обещает, что один `FOR UPDATE` сам по себе сохраняет правило после commit/rollback. |
| `CHECK` не предназначен для постоянной проверки других rows таблицы | [PostgreSQL 13: Constraints](https://www.postgresql.org/docs/13/ddl-constraints.html) | Инвариант `activeCount >= 1` сформулирован как cross-row правило, а не ложный `CHECK` на одной row. |
| Isolation задаётся до первого query или data-modification statement текущей transaction | [PostgreSQL 13: SET TRANSACTION](https://www.postgresql.org/docs/13/sql-set-transaction.html) | Пример не пытается менять `SET TRANSACTION` после уже начавшейся рабочей части. |
Фикстура повторно сверена с текстом:
- initial state: `anna=on`, `boris=on`, `activeCount=2`;
- T1 и T2 читают один snapshot и каждая проходит свою precondition;
- наивный schedule commit-ит разные rows и получает `activeCount=0`;
- teaching boundary берёт `[anna, boris]` в одном order, T2 ждёт T1,
затем читает `activeCount=1` и не делает write;
- retry-ветка обнаруживает stale model version, начинает operation заново и
отказывается от второго off;
- все **12** assertions вернули `true`.
Модель намеренно не имитирует MVCC, SQL planner, PostgreSQL lock manager,
Serializable Snapshot Isolation, SQLSTATE сервера, network, driver или
реальную нагрузку. Она доказывает только форму учебного schedule и контракт
полного retry.
Вердикт прохода: **пройден**.
## Проход 2. Редактура, глубина и голос М4 — пройдено
| Revision | Проблема и цена в начале | Практический артефакт | Голос и граница |
| --- | --- | --- | --- |
| Практика | Два success выключают разных дежурных, и смена остаётся без активного человека | contract invariant/scope, два SQL-shape и fixture из трёх веток | М4 связывает PHP/данные с конкурентным правилом, не выдавая модель за работу с production БД. |
| Механизм | Обёртка `transactional()` не доказывает, что reads и write видели совместимое состояние | матрица snapshot/lock/retry, SQL до первого query и whole-operation retry | Тон короткий: snapshot, returned rows, 40001 и side effect названы рядом с действием. |
| Полевой разбор | Два успешных запроса скрывают write skew, неполный scope либо неверный retry | evidence-table, диагностическая схема, `pg_locks` shape и фиксированный schedule | Автор отделяет wait, deadlock, serialization failure и business rejection, не придумывая incident или latency. |
Draft gate после финальной правки измерил основной текст без раздела
источников:
- практика — **10 993** знака;
- механизм — **10 950** знаков;
- полевой разбор — **10 079** знаков.
Все три текста находятся в целевом диапазоне 8–11 тыс. и в обязательном
диапазоне 5–15 тыс. знаков. В каждом есть проблема и цена в первых двух
абзацах, минимум пять смысловых разделов, figure с осмысленными
`alt`/`figcaption`, таблица с `caption`/`thead`, не менее двух технических
примеров, нумерованный маршрут и не менее двух официальных ссылок.
Проверка структуры revision:
| Revision | h2 | Figure | Table | Code blocks | Ordered list | Official links |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| Практика | 8 | 1 | 2 | 3 | 1 | 5 |
| Механизм | 8 | 1 | 1 | 4 | 1 | 6 |
| Полевой разбор | 8 | 1 | 2 | 4 | 1 | 7 |
Редакторский проход удалил повторы и сократил тексты до предметной схемы
«симптом → причина → проверка → действие». В них нет обещаний измеренного
throughput/latency, выполненного production-инцидента, готовой
распределённой платформы или реального lock trace.
Вердикт прохода: **пройден**.
## Проход 3. Визуал, fixture и preflight — пройдено в заданных границах
- `transaction-timeline-2021.svg` показывает один invariant, небезопасный
schedule двух reads/two writes и boundary, в которой T2 ждёт, перечитывает
state и отказывается от write.
- `transaction-isolation-matrix-2021.svg` сопоставляет Read Committed,
Repeatable Read и Serializable без ложного рейтинга; отдельной карточкой
показывает границу `SELECT ... FOR UPDATE`.
- `transaction-conflict-diagnosis-2021.svg` связывает четыре symptoms с
причиной, проверкой и действием: write skew, неполный scope, deadlock/wait
и `40001`.
- В каждом SVG есть `title`, `desc`, `role="img"`, вертикальный viewBox и
контрастные карточки. В них нет JavaScript, `foreignObject`, внешних URL и
data URI.
- Все SVG отрендерены локальным Sharp при ширине **375 px** и просмотрены
вручную. В первом проходе длинные подписи timeline и заголовок diagnosis
были разбиты на строки; после повторного рендера clipping, overlap и
горизонтальный overflow не обнаружены.
### Фактические команды и результаты
```sh
cd web
node --check scripts/upgrade-2021-01.mjs
npm run audit:draft -- scripts/upgrade-2021-01.mjs
node scripts/upgrade-2021-01.mjs --verify-fixture
xmllint --noout \
public/assets/editorial/2021/transaction-timeline-2021.svg \
public/assets/editorial/2021/transaction-isolation-matrix-2021.svg \
public/assets/editorial/2021/transaction-conflict-diagnosis-2021.svg
```
| Проверка | Реальный результат |
| --- | --- |
| `node --check` | код завершения 0 |
| Draft audit | PASS: 10 993 / 10 950 / 10 079 знаков тела |
| In-memory fixture | все 12 assertions вернули `true`; наивный schedule даёт 0 active, boundary/retry — 1 active |
| XML | все три SVG валидны, код завершения 0 |
| 375 px visual preflight | Sharp-render и ручной просмотр пройдены после исправления длинных строк |
| Scope/self-review | revision не меняют `date`/`author`; создано только пять разрешённых файлов P35 |
Не запускались настоящий PostgreSQL, две реальные session, SQL commands,
driver, query plan, real locks/waits, browser-review опубликенной страницы,
screen reader, CI, production build, deployment, HTTP или внешняя очередь.
Официальные документы проверялись как источники, но это не заменяет
integration test выбранной версии и schema.
## Итог
Статус: **тройное ревью пройдено; P35 принят к отдельной публикации**.
Автономный пакет содержит ровно пять разрешённых файлов:
1. `web/scripts/upgrade-2021-01.mjs`;
2. `editorial/reviews/2021-01-draft.md`;
3. `web/public/assets/editorial/2021/transaction-timeline-2021.svg`;
4. `web/public/assets/editorial/2021/transaction-isolation-matrix-2021.svg`;
5. `web/public/assets/editorial/2021/transaction-conflict-diagnosis-2021.svg`.
Автономный авторский пакет не менял registry, базовый архив или Git.
## Независимая интеграционная приёмка
Основной редактор 31 июля 2026 года подключил три revision к
<code>web/data/editorial-revisions.mjs</code>, не меняя базовый
<code>articles.json</code>, даты или автора архивных записей. В registry стало
100 revision. Официальные PostgreSQL 13-документы и опубликованный 12 ноября
2020 года release 13.1 сверены независимо: они поддерживают границы
Read Committed, Repeatable Read, Serializable и explicit locking, но не
превращают учебный schedule в запуск PostgreSQL.
| Проверка после интеграции | Реальный результат |
| --- | --- |
| Строгий audit трёх slug | PASS: 10 993 / 10 950 / 10 079 знаков; у каждой статьи есть figure, table и code examples |
| Production build | PASS: Next.js собрал 374 статические страницы |
| Независимый mobile visual review | PASS: основной редактор повторно просмотрел три SVG после Sharp-рендера в 375 px; clipping, overlap и overflow не обнаружены |
Ни этот отчёт, ни интеграция не утверждают запуск PostgreSQL, SQL, двух
session, настоящих lock/wait, browser или assistive technology.
Выпусковой вердикт: **ACCEPT**. Commit и push выполняются отдельной
публикационной операцией; Git остаётся источником её фактической записи.