funcnode-transaction

funcnode-transaction

Менеджер транзакций уровня приложения для Crystal.

Создан для модульных приложений, где каждый доменный модуль хранит данные самостоятельно — в собственных файлах, KV-хранилище, SQLite, где угодно — и общей базы данных, которая дала бы транзакции, нет. Библиотека обеспечивает изоляцию (сериализуемость) через блокировки по путям данных — консервативный 2PL над деревом путей, без дедлоков по построению — и откат через регистрируемые компенсации, не требуя от хранилищ модулей ровным счётом ничего.

Возможности

  • Иерархические read/write-блокировки по декларируемым путям данных (users/42/name), включая диапазоны id ({"users", 1000...2000}).
  • Нет дедлоков и голодания: все блокировки берутся атомарно до старта, честная FIFO-очередь без обгона по конфликту.
  • Стек компенсаций (on_rollback, step(undo:)), всегда точно соответствующий реально выполненным шагам.
  • Спроектирована для многопоточности (-Dpreview_mt).
  • Инструменты для dev и prod: assert_locked!, хук медленных транзакций, интроспекция.
  • Операции с блокировками за O(глубины пути): ~1,4 млн циклов grant+release в секунду независимо от числа активных блокировок.

Установка

Добавьте зависимость в shard.yml и выполните shards install:

dependencies:
  funcnode-transaction:
    gitlab: funcnode_crystal/funcnode-transaction

Быстрый старт

require "funcnode-transaction"

tm = Funcnode::Transaction::Manager.new

tm.run(read: "orders", write: [{"users", user_id, "name"}]) do |tx|
  old_name = read_name(user_id)
  write_name(user_id, new_name)
  tx.on_rollback { write_name(user_id, old_name) }
  # commit при нормальном выходе; при исключении зарегистрированные
  # компенсации выполняются в обратном порядке, исключение пробрасывается
end

Конфигурация

# объектом:
tm = Funcnode::Transaction::Manager.new(
  Funcnode::Transaction::Manager::Config.new(
    default_timeout: 10.seconds,          # таймаут ожидания блокировок по умолчанию
    max_waiting: 1_000,                   # предел очереди (backpressure)
    assertions_enabled: false,            # проверки assert_locked! (true в dev/test)
    slow_transaction_threshold: 2.seconds # порог watchdog-хука
  ))

# или путём к YAML-файлу: нет файла — создастся шаблон с дефолтами и
# комментариями, и первый запуск упадёт с ConfigError, чтобы оператор его
# увидел; битый файл — ConfigError тоже (приложение не поднимется):
tm = Funcnode::Transaction::Manager.new("./config/transactions.yaml")

# горячее изменение; если менеджер создан из файла — YAML обновится:
tm.configure { |c| c.default_timeout = 5.seconds }

Все параметры применяются «на горячую». Подробности и YAML-ключи — в руководстве.

Документация

Полная документация — в каталоге doc/:

  • Руководство — декларация путей и семантика конфликтов, оба API, компенсации, таймауты, эксплуатационный тулинг, многопоточность, производительность и ограничения v1.
  • Рецепты многопоточности — классические задачи и их решения: банковские счета, обедающие философы, заказ через несколько модулей, отчёты, диапазоны id, горячий счётчик. Запускаемые версии — в examples/.
  • Справочник API — генерируется из исходников (scripts/build_docs.ps1).
  • CHANGELOG.md — дельты между релизами; версии — это git-теги (vX.Y.Z) на ветке main.

Разработка

crystal spec                 # однопоточный прогон
crystal spec -Dpreview_mt    # многопоточный, включая стресс-спеку
crystal run -Dpreview_mt examples/demo.cr
crystal run --release benchmarks/lock_manager.cr
powershell -File scripts/build_docs.ps1   # перегенерация справочника API + favicon

Библиотека предназначена для серверов под Ubuntu 24 — полную матрицу спеков можно прогнать в production-parity контейнере (нужен запущенный Docker):

docker run --rm -v "<путь-к-репо>:/src:ro" crystallang/crystal:1.20.2 bash /src/scripts/linux_spec.sh

Успех — финальная строка LINUX MATRIX GREEN (Ubuntu 24.04, ...).

Участие в разработке

  1. Сделайте форк (https://gitlab.com/funcnode_crystal/funcnode-transaction/-/forks/new)
  2. Создайте ветку под фичу (git checkout -b my-new-feature)
  3. Закоммитьте изменения (git commit -am 'Add some feature')
  4. Запушьте ветку (git push origin my-new-feature)
  5. Создайте Merge Request

Авторы

  • Василий Бутер — автор и мейнтейнер
Repository

funcnode-transaction

Owner
Statistic
  • 0
  • 0
  • 0
  • 0
  • 0
  • about 6 hours ago
  • July 12, 2026
License

MIT License

Links
Synced at

Sat, 01 Aug 2026 21:37:59 GMT

Languages