PHPackages                             inneair/transaction-bundle - 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. inneair/transaction-bundle

ActiveSymfony-bundle

inneair/transaction-bundle
==========================

Transaction bundle for Symfony

1.0.3(8y ago)1013.1k3Apache-2.0PHPPHP &gt;=5.6

Since Jan 5Pushed 8y ago4 watchersCompare

[ Source](https://github.com/inneair/transaction-bundle)[ Packagist](https://packagist.org/packages/inneair/transaction-bundle)[ RSS](/packages/inneair-transaction-bundle/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)Dependencies (9)Versions (5)Used By (0)

Inneair Transaction bundle for Symfony
======================================

[](#inneair-transaction-bundle-for-symfony)

[![Build status](https://camo.githubusercontent.com/df3ae6992d3bcfdbc1cee4dbcb71892688e69aef6eba31fa70159564842f6ee7/68747470733a2f2f7472617669732d63692e6f72672f496e6e656169722f7472616e73616374696f6e2d62756e646c652e7376673f6272616e63683d6d6173746572)](http://travis-ci.org/Inneair/transaction-bundle "Build status on Travis CI")[![Coverage status](https://camo.githubusercontent.com/426fe6ad2939f70a8b91b6ab6242c6d5a524bae7d35957e3b6fa0707d7ae82ae/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f496e6e656169722f7472616e73616374696f6e2d62756e646c652f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/Inneair/transaction-bundle?branch=master "Test coverage on Coveralls")[![SensioLabs Insight](https://camo.githubusercontent.com/1c8a508fc3aa0f9ece705f2c7e56462d7b181178db94defac1e1ae0712c9071c/68747470733a2f2f696d672e736869656c64732e696f2f73656e73696f6c6162732f692f64643035643161382d663961382d343132612d623264342d6561316432386562653232332e737667)](https://insight.sensiolabs.com/projects/dd05d1a8-f9a8-412a-b2d4-ea1d28ebe223)

[![Latest stable version](https://camo.githubusercontent.com/9a3a832beae8f2383101405b7990a49470212c56ad6b51cd7ecb2f0cb6b57c92/68747470733a2f2f706f7365722e707567782e6f72672f696e6e656169722f7472616e73616374696f6e2d62756e646c652f762f737461626c65)](https://packagist.org/packages/Inneair/transaction-bundle "Bundle packages on Packagist")[![Latest unstable version](https://camo.githubusercontent.com/3ef928c9efeb902d39ac17f671bf1c96df3960b2935d2473b0c3b66202d8716c/68747470733a2f2f706f7365722e707567782e6f72672f696e6e656169722f7472616e73616374696f6e2d62756e646c652f762f756e737461626c65)](https://packagist.org/packages/Inneair/transaction-bundle "Bundle packages on Packagist")[![License](https://camo.githubusercontent.com/4cc093f495dcf7a02994f5569641dfcd90a2a23f08bc5028e4f494be1be64557/68747470733a2f2f706f7365722e707567782e6f72672f696e6e656169722f7472616e73616374696f6e2d62756e646c652f6c6963656e7365)](https://packagist.org/packages/Inneair/transaction-bundle "Bundle packages on Packagist")

[![Scrutinizer Code Quality](https://camo.githubusercontent.com/100482b1d49a9c00d3ae20c48913c0fbecfd937f2e440b7e8470bd5929b97e33/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f496e6e656169722f7472616e73616374696f6e2d62756e646c652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/Inneair/transaction-bundle/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/85666dae1e34bbfef6009d388862ea6d015b53a802aae404a41bc2120714c941/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f496e6e656169722f7472616e73616374696f6e2d62756e646c652f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/Inneair/transaction-bundle/?branch=master)[![Build Status](https://camo.githubusercontent.com/fa2dd137489a8b26f0b9651b6bba63bbdc1eb8992f1152a886cacb76733415e0/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f496e6e656169722f7472616e73616374696f6e2d62756e646c652f6261646765732f6275696c642e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/Inneair/transaction-bundle/build-status/master)

This bundle provides an easy way to manage transactions with annotations. It is highly inspired from the one provided as example by the [JMSAopBundle](https://github.com/schmittjoh/JMSAopBundle), but provides :

- a configurable policy, allowing a class/method to choose whereas a new transaction must/shall be opened, or must not exist at all.
- an inheritance of the transactional context, from an annotated class/method to an other.
- a configurable list of exceptions that shall not trigger a rollback when a method call completes with an exception.

**Why use this bundle instead of the standard behaviour of the Doctrine-ORM's entity manager?**

If you dig into the code of the Doctrine-ORM's entity manager, we can see the entity manager already supports recursive calls of the method `begin_transaction`, and starts really a transaction for the top call. However, it means this behaviour - consisting of determining if a transaction shall be opened - is coded in the persistence layer. Transactions shall be managed by business components, who are able to state what's the expected behaviour. The ORM is part of the persistence layer, and shall not be aware of this.

Summary
=======

[](#summary)

- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
- [Example](#example)

Installation
====================================================

[](#installation)

1. Download
-----------

[](#1-download)

The bundle can be installed in your Symfony project with [Composer](https://getcomposer.org/ "Get Composer"). Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle:

```
composer require inneair/transaction-bundle
```

2. Activation
-------------

[](#2-activation)

Activate the [JMSAopBundle](https://github.com/schmittjoh/JMSAopBundle) first, following [those instructions](http://jmsyst.com/bundles/JMSAopBundle) for installation and configuration.

Activate the bundle by modifying the `app/AppKernel.php` file:

```

        Company\Bundle\MyException1
        Company\Bundle\MyException2

```

3. Reference
------------

[](#3-reference)

`strict_mode`: whether classes must implement the `TransactionalAwareInterface` interface, so as the annotation `@Transactional` is read. Default is `false`.

`default_policy`: default transactional policy when none policy is set in the annotation, which must be one of these values:

- `required`: a transaction must be started if no transactional context already exist.
- `not-required`: a transaction must not be started, whatever there is an existing transaction context.
- `nested`: a new transaction (use of save points) must be started, even if there is already a transactional context. Save points must be enabled in the connection parameters (see the [DoctrineBundle configuration reference](http://symfony.com/doc/current/bundles/DoctrineBundle/configuration.html "DoctrineBundle configuration reference")). **However, we strongly recommend to avoid the use of nested transactions. Components shall be designed to use the `required` or `not-required` strategies.**

Default is `required`.

`no_rollback_exceptions`: array of full qualified class names of exceptions, for which rollback won't be triggered if a transactional context is alive. Use of this parameter shall be exceptional. Default is the empty array.

Usage
======================================

[](#usage)

Inside any container-managed component, insert the annotation `@Transaction` to enable automatic transaction management. When a parameter is defined in the annotation, it overwrites the default value in the bundle configuration.

**WARNING: keep separated concerns, and decoupled components. Transaction management in controllers, though frequently shown in examples, is not a good design orientation. Controllers in web applications are HTTP interfaces, and their role is basically to receive requests, call business services, return responses: by definition, they belong to the presentation layer. Transactions shall be managed by business components only.**

1. Whole service
----------------

[](#1-whole-service)

The annotation can be inserted in the PHP doc block of the class itself, allowing transaction management for all public methods. All annotation parameters are optional. If none is specified, the default configuration of the bundle applies (see above).

```
use Exception;
use MyCompany\MyBundle\MyException;
use Inneair\TransactionBundle\Annotation\Transactional;

/**
 * @Transactional(policy=Transactional::REQUIRED, noRollbackExceptions={Exception::class, MyException::class})
 */
class AccountManager
{
    // ...
}
```

2. Single method
----------------

[](#2-single-method)

The annotation can be inserted in the PHP doc block of a public method itself, to allow transaction management. The annotation parameters are optional. If none is specified, the default configuration of the bundle applies (see above).

```
use Exception;
use MyCompany\MyBundle\MyException;
use Inneair\TransactionBundle\Annotation\Transactional;

class AccountManager
{
    /**
     * @Transactional(policy=Transactional::REQUIRED, noRollbackExceptions={Exception::class, MyException::class})
     */
    public function createAccount(Account $account)
    {
        // ...
    }
}
```

A concrete example
=====================================================

[](#a-concrete-example)

Let's imagine an application dealing with human resources, and organization of people among many companies. A good strategy (among other ones) would be to implement:

- a business service for the management of companies `CompanyManager`.
- a business service for the management of people in these companies `PersonManager`.

Let's focus on the user story: **"I want to register a new person in a new company (in one step)"**.

1. The `Company` model
----------------------

[](#1-the-company-model)

The company is at the top of our business model, it is standalone (no dependencies).

```
