Спецпроекты

LedgerCore

Учёт по двойной записи: проводки, балансы и сторно. Повторная команда возвращает исходный результат, а конкурирующие списания блокируют счета до проверки остатка.

Тип
Сервис учёта
Стек
Java · Spring Boot · PostgreSQL
Код
Открыт на GitHub
Год
2026

Весы двойной записи

Проводка кладёт гири на обе чаши: дебет и кредит. Штамп опускается, только когда коромысло в равновесии, а пробитый талон с тем же ключом второй раз не проходит.

LEDGERCORE#7#8#9#10#11
Штамп коммита: опускается, только когда коромысло ровноеГири проводок: дебет слева, кредит справа, размер по суммеКартотека квитанций и талон с пробитым ключомНастольная модель LedgerCore, сервиса двойной записи на Java, Spring Boot и PostgreSQL. В транзакции две и больше проводки, и по каждой валюте дебет равен кредиту: на левой чаше гири дебета, на правой кредита, а вес гири — сумма в целых копейках. Штамп коммита опускается, только когда коромысло ровное, и сразу видит весь набор проводок; неравная пара оставляет коромысло наклонённым, а штамп запертым. Каждый запрос приходит на талоне с ключом идемпотентности: пробойник узнаёт уже пробитый ключ и возвращает исходную квитанцию вместо нового штампа. Историю не правят: сторно кладёт на чаши новую зеркальную пару с перевёрнутыми сторонами, а прежние гири остаются. Стенд показывает только последние гири на чашах и последние шесть квитанций, в базе история хранится целиком.

Модель

В каждой транзакции две и больше проводки, и по каждой валюте дебет равен кредиту. Суммы хранятся целыми копейками в 64 битах, дробных денег в базе нет. Балансы выводятся из проводок, а история не редактируется: сторно — это новая транзакция с перевёрнутыми сторонами.

Запись

Каждый запрос несёт ключ идемпотентности. Повтор с тем же ключом и тем же телом возвращает исходную транзакцию, с другим телом — отказ. Затронутые счета блокируются в стабильном порядке, поэтому из двух одновременных списаний последнего рубля пройдёт только одно. Отложенные ограничения PostgreSQL проверяют весь набор проводок в момент коммита.

Технически

  • Двойная запись с проверкой баланса по каждой валюте.
  • Ключ идемпотентности с advisory-блокировкой PostgreSQL.
  • Блокировка счетов в порядке UUID против гонок.
  • Сторно только новой транзакцией, одно на исходную.
  • Изменение и удаление проводок запрещены на уровне базы.
Код на GitHub

Обсудим ваш проект?

Обсудить проект