Перейти к содержанию

Financial correctness

Раздел 05

Тип материала — инженерная модель. HYPOTHETICAL — значения, состояния и схемы.

Инварианты и границы

Финансовый эффект определяется сохранённой операцией, которая связана с экономическим основанием. Exactly-once delivery описывает доставку в определённом протоколе. Повтор с новым business ID способен создать второй сбалансированный journal. Unique constraint по области операции, сравнение параметров и атомарный commit журнала защищают эффект в пределах одной БД.

Проводки должны балансироваться внутри journal и currency. Нулевой итог по всей таблице не обнаружит ошибочное направление, пропуск пары или дубликат пары. Кредитный и дебетовый знак выбираются по типу счёта. Денежные значения хранятся в точных единицах с явно заданной валютой и scale. FX требует отдельных балансирующих счетов по каждой валюте. Остаток может участвовать в авторитетном guard, если его изменение атомарно с posting, он имеет определённого владельца и регулярно сверяется с журналом. UI projection используется для чтения.

flowchart LR
 C[Stable business command] --> T[Atomic operation and journal commit]
 T --> P[Balance projection]
 T --> O[Outbox]
 T --> R[Independent reconciliation]
 E[External statement] --> R

Нормальная проводка

sequenceDiagram
 participant C as Client
 participant L as Ledger transaction
 participant D as Ledger DB
 C->>L: Submit operation ID and amount
 L->>D: Check identity and lock position
 L->>D: Write balanced legs and result
 D-->>C: Return committed journal reference

Lost ACK и ambiguous commit

sequenceDiagram
 participant C as Client
 participant D as Ledger DB
 C->>D: Submit operation K
 Note over D: Journal J committed
 D--xC: ACK lost
 C->>D: Retry K with identical parameters
 D-->>C: Return stored reference J
  1. Принять перевод 30 EUR с ID K.
  2. Зафиксировать ID, параметры и журнал J одним commit.
  3. При timeout открыть проверку исхода. На авторитетном writer повторить ту же операцию или прочитать сохранённый результат. Отсутствие записи на отстающей реплике недостаточно для нового запроса.
  4. Если исход относится к PSP, разрешить его по PSP lookup, подписанному callback и settlement evidence. Истечение окна дедупликации переводит операцию в review.
Срез Durable state Наблюдение
До commit K отсутствует Клиент ожидает
После отказа K → J, legs −30 и +30 ACK неизвестен
После retry Тот же J Второй эффект отсутствует

Конкурентный расход

  1. При available 100 одновременно поступают два расхода по 70 с разными ID.
  2. Оба читают предварительное значение. Под lock или serializable transaction первая операция фиксирует legs и уменьшает available до 30.
  3. Вторая заново проверяет состояние либо повторяет всю aborted transaction после serialization error. При 30 расход отклоняется.
  4. Заблокировать счета в устойчивом порядке для переводов между ними. Guard и legs держать в одном commit.
Срез Available Durable postings
До гонки 100 Исходное состояние
После первого commit 30 Один расход 70
После retry второго 30 Один расход 70

Исправление после закрытия

  1. Проводка J на 60 зафиксирована и вошла в отчёт V1. Независимый statement подтверждает 50.
  2. Сверить identity и исключить ожидаемую задержку, комиссию или частичный расчёт.
  3. Approver создаёт корректирующий journal на разницу либо reversal и replacement согласно утверждённой policy. Сохранить ссылку на J и evidence.
  4. Выпустить V2 с собственным cut и lineage. Retry correction по тому же ID возвращает прежний результат.
Срез Учёт Evidence
До обнаружения J = 60 Отчёт V1
После расхождения J = 60 Statement 50 и exception
После исправления J и adjustment −10 V1 и V2 со связью

Compensation совершает новый эффект. Rollback отменяет незавершённую транзакцию. Сверка сравнивает независимые IDs, multiplicity, валюты и суммы на явном cut. Audit trail связывает инициатора, policy version, исходное событие, journal, correction и выпуск отчёта.

Первичные источники