<commit_before>Transactions and Concurrency
============================

.. _transactions-and-concurrency_transaction-demarcation:

Transaction Demarcation
-----------------------

Transaction demarcation is the task of defining your transaction
boundaries. Proper transaction demarcation is very important
because if not done properly it can negatively affect the
performance of your application. Many databases and database
abstraction layers like PDO by default operate in auto-commit mode,
which means that every single SQL statement is wrapped in a small
transaction. Without any explicit transaction demarcation from your
side, this quickly results in poor performance because transactions
are not cheap.

For the most part, Doctrine 2 already takes care of proper
transaction demarcation for you: All the write operations
(INSERT/UPDATE/DELETE) are queued until ``EntityManager#flush()``
is invoked which wraps all of these changes in a single
transaction.

However, Doctrine 2 also allows (and encourages) you to take over
and control transaction demarcation yourself.

These are two ways to deal with transactions when using the
Doctrine ORM and are now described in more detail.

.. _transactions-and-concurrency_approach-implicitly:

Approach 1: Implicitly
~~~~~~~~~~~~~~~~~~~~~~

The first approach is to use the implicit transaction handling
provided by the Doctrine ORM EntityManager. Given the following
code snippet, without any explicit transaction demarcation:

.. code-block:: php

    <?php
    // $em instanceof EntityManager
    $user = new User;
    $user->setName('George');
    $em->persist($user);
    $em->flush();

Since we do not do any custom transaction demarcation in the above
code, ``EntityManager#flush()`` will begin and commit/rollback a
transaction. This behavior is made possible by the aggregation of
the DML operations by the Doctrine ORM and is sufficient if all the
data manipulation that is part of a unit of work happens through
the domain model and thus the ORM.

.. _transactions-and-concurrency_approach-explicitly:

Approach 2: Explicitly
~~~~~~~~~~~~~~~~~~~~~~

The explicit alternative is to use the ``Doctrine\DBAL\Connection``
API directly to control the transaction boundaries. The code then
looks like this:

.. code-block:: php

    <?php
    // $em instanceof EntityManager
    $em->getConnection()->beginTransaction(); // suspend auto-commit
    try {
        //... do some work
        $user = new User;
        $user->setName('George');
        $em->persist($user);
        $em->flush();
        $em->getConnection()->commit();
    } catch (Exception $e) {
        $em->getConnection()->rollback();
        throw $e;
    }

Explicit transaction demarcation is required when you want to
include custom DBAL operations in a unit of work or when you want
to make use of some methods of the ``EntityManager`` API that
require an active transaction. Such methods will throw a
``TransactionRequiredException`` to inform you of that
requirement.

A more convenient alternative for explicit transaction demarcation is the use
of provided control abstractions in the form of
``Connection#transactional($func)`` and ``EntityManager#transactional($func)``.
When used, these control abstractions ensure that you never forget to rollback
the transaction, in addition to the obvious code reduction. An example that is
functionally equivalent to the previously shown code looks as follows:

.. code-block:: php

    <?php
    // $em instanceof EntityManager
    $em->transactional(function($em) {
        //... do some work
        $user = new User;
        $user->setName('George');
        $em->persist($user);
    });
<commit_msg>Fixing method name 'rollBack', which was documented as 'rollback'<commit_after>Transactions and Concurrency
============================

.. _transactions-and-concurrency_transaction-demarcation:

Transaction Demarcation
-----------------------

Transaction demarcation is the task of defining your transaction
boundaries. Proper transaction demarcation is very important
because if not done properly it can negatively affect the
performance of your application. Many databases and database
abstraction layers like PDO by default operate in auto-commit mode,
which means that every single SQL statement is wrapped in a small
transaction. Without any explicit transaction demarcation from your
side, this quickly results in poor performance because transactions
are not cheap.

For the most part, Doctrine 2 already takes care of proper
transaction demarcation for you: All the write operations
(INSERT/UPDATE/DELETE) are queued until ``EntityManager#flush()``
is invoked which wraps all of these changes in a single
transaction.

However, Doctrine 2 also allows (and encourages) you to take over
and control transaction demarcation yourself.

These are two ways to deal with transactions when using the
Doctrine ORM and are now described in more detail.

.. _transactions-and-concurrency_approach-implicitly:

Approach 1: Implicitly
~~~~~~~~~~~~~~~~~~~~~~

The first approach is to use the implicit transaction handling
provided by the Doctrine ORM EntityManager. Given the following
code snippet, without any explicit transaction demarcation:

.. code-block:: php

    <?php
    // $em instanceof EntityManager
    $user = new User;
    $user->setName('George');
    $em->persist($user);
    $em->flush();

Since we do not do any custom transaction demarcation in the above
code, ``EntityManager#flush()`` will begin and commit/rollback a
transaction. This behavior is made possible by the aggregation of
the DML operations by the Doctrine ORM and is sufficient if all the
data manipulation that is part of a unit of work happens through
the domain model and thus the ORM.

.. _transactions-and-concurrency_approach-explicitly:

Approach 2: Explicitly
~~~~~~~~~~~~~~~~~~~~~~

The explicit alternative is to use the ``Doctrine\DBAL\Connection``
API directly to control the transaction boundaries. The code then
looks like this:

.. code-block:: php

    <?php
    // $em instanceof EntityManager
    $em->getConnection()->beginTransaction(); // suspend auto-commit
    try {
        //... do some work
        $user = new User;
        $user->setName('George');
        $em->persist($user);
        $em->flush();
        $em->getConnection()->commit();
    } catch (Exception $e) {
        $em->getConnection()->rollBack();
        throw $e;
    }

Explicit transaction demarcation is required when you want to
include custom DBAL operations in a unit of work or when you want
to make use of some methods of the ``EntityManager`` API that
require an active transaction. Such methods will throw a
``TransactionRequiredException`` to inform you of that
requirement.

A more convenient alternative for explicit transaction demarcation is the use
of provided control abstractions in the form of
``Connection#transactional($func)`` and ``EntityManager#transactional($func)``.
When used, these control abstractions ensure that you never forget to rollback
the transaction, in addition to the obvious code reduction. An example that is
functionally equivalent to the previously shown code looks as follows:

.. code-block:: php

    <?php
    // $em instanceof EntityManager
    $em->transactional(function($em) {
        //... do some work
        $user = new User;
        $user->setName('George');
        $em->persist($user);
    });

{'fraction_non_alphanumeric': 0.09676113360323886, 'fraction_numerical': 0.0010796221322537112, 'mean_word_length': 3.997302764666217, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3101588', 'n_tokens_mistral': 1858, 'n_tokens_neox': 1809, 'n_words': 866}