PHPackages                             sbooker/transaction-manager - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. sbooker/transaction-manager

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

sbooker/transaction-manager
===========================

Abstraction for transaction control on an application tier.

3.0.0(1mo ago)16.9k1[1 PRs](https://github.com/sbooker/transaction-manager/pulls)6MITPHPPHP ^8.1CI failing

Since Jun 3Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/sbooker/transaction-manager)[ Packagist](https://packagist.org/packages/sbooker/transaction-manager)[ RSS](/packages/sbooker-transaction-manager/feed)WikiDiscussions master Synced 5d ago

READMEChangelog (2)Dependencies (2)Versions (18)Used By (6)

[Read in English](README_EN.md)

Менеджер Транзакций (`sbooker/transaction-manager`)
===================================================

[](#менеджер-транзакций-sbookertransaction-manager)

[![Latest Version](https://camo.githubusercontent.com/5dd3b0fe7a1f82a196188de3445852012ad2cddcf5cc13fbff9d9bc8bd6fad5d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f73626f6f6b65722f7472616e73616374696f6e2d6d616e616765722e7376673f7374796c653d666c61742d737175617265)](https://img.shields.io/packagist/v/sbooker/transaction-manager)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/sbooker/transaction-manager/blob/master/LICENSE)[![PHP Version](https://camo.githubusercontent.com/13285d6168183b7df0f34c8befc3c084aa886341a3f6e7a0ea40e50d1d00d711/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f73626f6f6b65722f7472616e73616374696f6e2d6d616e616765722e7376673f7374796c653d666c61742d737175617265)](https://php.net)[![Total Downloads](https://camo.githubusercontent.com/072a1099d7cfe4f7663e24d5b6fd443eb687db3dcfb0baa8611d2d85ff068fad/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f73626f6f6b65722f7472616e73616374696f6e2d6d616e616765722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/sbooker/transaction-manager)[![codecov](https://camo.githubusercontent.com/8ff914ff3efef7c877ce14f8e9c7482af69b916326cb211104bc3cb24ff546c9/68747470733a2f2f636f6465636f762e696f2f67682f73626f6f6b65722f7472616e73616374696f6e2d6d616e616765722f6272616e63682f322e782e782f67726170682f62616467652e7376673f746f6b656e3d337543493974304d3251)](https://codecov.io/gh/sbooker/transaction-manager)

Реализация паттерна Unit of Work, которая навязывает безопасные и явные практики управления транзакциями и предоставляет мощный механизм хуков перед коммитом.

Философия и назначение
----------------------

[](#философия-и-назначение)

Библиотека спроектирована с учетом работы в долгоживущих процессах (воркерах, консьюмерах) и построена на трех ключевых принципах:

1. **Явные границы транзакций.** Библиотека намеренно не предоставляет публичные методы `begin()` и `commit()`. Единственный способ выполнить операцию — через замыкание `transactional()`. Такой подход делает границы транзакции абсолютно явными и защищает от трудноуловимых багов, когда `begin()` и `commit()` разнесены по разным частям кода.
2. **Безопасная работа с сущностями.** Библиотека предоставляет единственный метод для извлечения сущностей с целью их изменения — `getLocked()`. Это также сделано намеренно, чтобы:

    - **Заставить разработчика использовать блокировки** (пессимистичные или оптимистичные, в зависимости от реализации `TransactionHandler`), что предотвращает гонки данных по умолчанию.
    - **Устранить необходимость в репозиториях** внутри кода, который изменяет состояние системы. Ваш прикладной код зависит только от `TransactionManager`, что делает его проще и чище.
3. **Автоматическое управление состоянием.** После каждой операции transactional() менеджер транзакций полностью очищает свое внутреннее состояние. Это предотвращает утечки памяти и гарантирует, что каждая транзакция начинается "с чистого листа", что критически важно для надежной работы воркеров.

Ключевые особенности
--------------------

[](#ключевые-особенности)

- **Автоматическая очистка состояния:** После каждого коммита или отката менеджер транзакций полностью очищает свое внутреннее состояние (Unit of Work) и состояние нижележащего обработчика. Это предотвращает утечки памяти и обеспечивает изоляцию операций в долгоживущих процессах.
- **Явные границы транзакций:** Метод `transactional()` — единственный способ выполнить атомарную операцию.
- **Единый механизм загрузки с блокировкой:** Метод `getLocked()` — единственный способ получить сущность для изменения, что заставляет использовать блокировки и предотвращает проблемы параллельного доступа.
- **Паттерн Unit of Work:** Управляет списком измененных и новых объектов и сохраняет их все в одной транзакции.
- **Абстракция над ORM:** Ваша бизнес-логика зависит только от `TransactionManager`.
- **Поддержка вложенных транзакций:** Безопасные вызовы `transactional()` внутри другого `transactional()`.
- **Хук перед коммитом (`PreCommitEntityProcessor`):** Позволяет создавать мощные инструменты, такие как сохранение доменных событий.

Установка
---------

[](#установка)

```
composer require sbooker/transaction-manager
```

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

[](#быстрый-старт)

### Шаг 1: Подключите `TransactionHandler`

[](#шаг-1-подключите-transactionhandler)

Для работы `TransactionManager` требуется "мост" к вашей ORM. Мы предоставляем готовые реализации:

- **Для Doctrine ORM:** `composer require sbooker/doctrine-transaction-handler`
- **Для Yii2 Active Record:** `composer require sbooker/yii2-ar-transaction-handler`

Если вы используете другую ORM, вам нужно будет создать свой адаптер, реализующий интерфейс `TransactionHandler`.

### Шаг 2: Соберите `TransactionManager`

[](#шаг-2-соберите-transactionmanager)

```
// bootstrap.php или ваш DI-контейнер
/** @var Sbooker\DoctrineTransactionHandler\TransactionHandler $transactionHandler */
$transactionManager = new Sbooker\TransactionManager\TransactionManager($transactionHandler);
```

### Шаг 3: Используйте в прикладном коде

[](#шаг-3-используйте-в-прикладном-коде)

#### Пример создания сущности

[](#пример-создания-сущности)

```
// src/Products/Application/Handler.php
final class Handler
{
    private TransactionManager $transactionManager;
    // ...

    public function handle(Command $command): void
    {
        $this->transactionManager->transactional(function () use ($command): void {
            $product = new Product(/* ... */);
            // Регистрируем новую сущность для сохранения
            $this->transactionManager->persist($product);
        });
        // После выхода из этого блока, внутреннее состояние менеджера полностью очищено.
    }
}
```

#### Пример изменения сущности

[](#пример-изменения-сущности)

Этот пример демонстрирует всю мощь подхода. Обратите внимание: здесь нет репозиториев.

```
// src/Products/Application/Handler.php
final class Handler
{
    private TransactionManager $transactionManager;
    // ...

    public function handle(Command $command): void
    {
        $this->transactionManager->transactional(function () use ($command): void {
            // 1. Получаем сущность с блокировкой. Это единственный способ.
            /** @var Product|null $product */
            $product = $this->transactionManager->getLocked(Product::class, $command->getProductId());

            if (null === $product) {
                throw new Exception('Product not found.');
            }

            // 2. Выполняем бизнес-логику
            $product->changeName($command->getNewName());

            // 3. НЕ НУЖНО вызывать persist() или save()!
            // Сущность, полученная через getLocked(), уже находится под управлением Unit of Work.
        });
        // Здесь Unit of Work также полностью очищен.
    }
}
```

### Шаг 4 (Продвинутый): Добавление `PreCommitProcessor`

[](#шаг-4-продвинутый-добавление-precommitprocessor)

Зарегистрируйте ваш процессор в конструкторе `TransactionManager`, и он будет автоматически вызываться для всех сущностей (`new Product` из первого примера и `$product` из второго) перед коммитом.

```
// bootstrap.php или ваш DI-контейнер
$loggingProcessor = new LoggingProcessor($logger);
$transactionManager = new Sbooker\TransactionManager\TransactionManager(
    $transactionHandler,
    $loggingProcessor
);
```

**Внимание!**

```
$entityId = ...;
$transactionManager->transactional(function () use ($transactionManager, $entityId) {
    $entity = new SomeEntity($entityId);
    $transactionManager->persist($entity);

    // Depends on TransactionHandler implementation $persistedEntity may be null in same transaction with persist
    $persistedEntity = $transactionManager->getLocked($entityId);
}
```

License
-------

[](#license)

See [LICENSE](https://github.com/sbooker/transaction-manager/blob/master/LICENSE) file.

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance90

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity72

Established project with proven stability

 Bus Factor1

Top contributor holds 89.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~151 days

Recently: every ~234 days

Total

15

Last Release

58d ago

Major Versions

0.9.0 → 1.0.12021-01-09

1.1.0 → 2.0.02021-08-29

2.2.0 → 3.x-dev2022-08-28

2.4.0 → 3.0.02026-03-20

PHP version history (4 changes)1.0.0PHP ^7.4

0.9.0PHP ^7.1

1.0.1PHP ^7.4 || ^8.0

3.0.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/f97b1f6ea03776dda6e0ec26d1ff3a3309972d65bd1376eb111c2b35017af339?d=identicon)[sbooker](/maintainers/sbooker)

---

Top Contributors

[![sbooker](https://avatars.githubusercontent.com/u/3658174?v=4)](https://github.com/sbooker "sbooker (17 commits)")[![s0lus](https://avatars.githubusercontent.com/u/4124371?v=4)](https://github.com/s0lus "s0lus (2 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/sbooker-transaction-manager/health.svg)

```
[![Health](https://phpackages.com/badges/sbooker-transaction-manager/health.svg)](https://phpackages.com/packages/sbooker-transaction-manager)
```

###  Alternatives

[sastrawi/sastrawi

PHP library for stemming Indonesian language (Bahasa Indonesia)

43972.0k4](/packages/sastrawi-sastrawi)[magefan/module-wysiwyg-advanced

Extend TinyMCE 4 in Magento 2

762.3M1](/packages/magefan-module-wysiwyg-advanced)[protonlabs/bitcoin

PHP Bitcoin library with functions for transactions, signatures, serialization, Random/Deterministic ECDSA keys, blocks, RPC bindings

33187.4k8](/packages/protonlabs-bitcoin)[webtorque7/inpage-modules

Adds module blocks to a SilverStripe website.

191.3k](/packages/webtorque7-inpage-modules)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
