@@ -9,71 +9,150 @@ Transactions
99 :values: tutorial
1010
1111.. meta::
12- :keywords: php framework, odm, code example
12+ :keywords: php framework, odm, rollback, commit, callback, code example, acid, atomic, consistent, isolated, durable
1313
14- MongoDB transactions require the following software and topology:
14+ .. contents:: On this page
15+ :local:
16+ :backlinks: none
17+ :depth: 2
18+ :class: singlecol
19+
20+ Overview
21+ --------
22+
23+ In this guide, you can learn how to perform a **transaction** in MongoDB by
24+ using the {+odm-long+}. Transactions let you run a sequence of write operations
25+ that update the data only after the transaction is committed.
26+
27+ If the transaction fails, the PHP library that manages MongoDB operations
28+ for {+odm-short+} ensures that MongoDB discards all the changes made within
29+ the transaction before they become visible. This property of transactions
30+ that ensures that all changes within a transaction are either applied or
31+ discarded is called **atomicity**.
32+
33+ MongoDB performs write operations on single documents atomically. If you
34+ need atomicity in write operations on multiple documents or data consistency
35+ across multiple documents for your operations, run them in a multi-document
36+ transaction.
37+
38+ Multi-document transactions are **ACID compliant** because MongoDB
39+ guarantees that the data in your transaction operations remains consistent,
40+ even if the driver encounters unexpected errors.
41+
42+ Learn how to perform transactions in the following sections of this guide:
43+
44+ - :ref:`laravel-transaction-requirements`
45+ - :ref:`laravel-transaction-callback`
46+ - :ref:`laravel-transaction-commit`
47+ - :ref:`laravel-transaction-rollback`
48+
49+ .. tip::
50+
51+ To learn more about transactions in MongoDB, see :manual:`Transactions </core/transactions/>`
52+ in the {+server-docs-name+}.
53+
54+ .. _laravel-transaction-requirements:
55+
56+ Requirements and Limitations
57+ ----------------------------
58+
59+ To perform transactions in MongoDB, you must use the following MongoDB
60+ version and topology:
1561
1662- MongoDB version 4.0 or later
1763- A replica set deployment or sharded cluster
1864
19- You can find more information :manual:`in the MongoDB docs </core/transactions/>`
65+ MongoDB server and {+odm-short+} have the following limitations:
2066
21- .. code-block:: php
67+ - In MongoDB versions 4.2 and earlier, write operations performed within a
68+ transaction must be on existing collections. In MongoDB versions 4.4 and
69+ later, the server automatically creates collections as necessary when
70+ you perform write operations in a transaction. To learn more about this
71+ limitation, see :manual:`Create Collections and Indexes in a Transaction </core/transactions/#create-collections-and-indexes-in-a-transaction>`
72+ in the {+server-docs-name+}.
73+ - MongoDB does not support nested transactions. If you attempt to start a
74+ transaction within another one, the extension raises a ``RuntimeException``.
75+ To learn more about this limitation, see :manual:`Transactions and Sessions </core/transactions/#transactions-and-sessions>`
76+ in the {+server-docs-name+}.
77+ - The {+odm-long+} does not support the database testing traits
78+ ``Illuminate\Foundation\Testing\DatabaseTransactions`` and ``Illuminate\Foundation\Testing\RefreshDatabase``.
79+ As a workaround, you can create migrations with the ``Illuminate\Foundation\Testing\DatabaseMigrations``
80+ trait to reset the database after each test.
2281
23- DB::transaction(function () {
24- User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']);
25- DB::collection('users')->where('name', 'john')->update(['age' => 20]);
26- DB::collection('users')->where('name', 'john')->delete();
27- });
82+ .. _laravel-transaction-callback:
2883
29- .. code-block:: php
84+ Run a Transaction in a Callback
85+ -------------------------------
86+
87+ This section shows how you can run a transaction in a callback.
3088
31- // begin a transaction
32- DB::beginTransaction();
33- User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']);
34- DB::collection('users')->where('name', 'john')->update(['age' => 20]);
35- DB::collection('users')->where('name', 'john')->delete();
89+ When using this method of running a transaction, all the code in the
90+ callback method runs as a single transaction.
3691
37- // commit changes
38- DB::commit();
92+ In the following example, the transaction consists of write operations that
93+ transfer the funds from a bank account, represented by the ``Account`` model,
94+ to another account:
3995
40- To abort a transaction, call the ``rollBack`` method at any point during the transaction:
96+ .. literalinclude:: /includes/fundamentals/transactions/TransactionsTest.php
97+ :language: php
98+ :dedent:
99+ :start-after: begin transaction callback
100+ :end-before: end transaction callback
101+
102+ You can optionally pass the maximum number of times to retry a failed transaction as the second parameter as shown in the following code example:
41103
42104.. code-block:: php
105+ :emphasize-lines: 4
43106
44- DB::beginTransaction();
45- User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']);
107+ DB::transaction(function() {
108+ // transaction code
109+ },
110+ retries: 5,
111+ );
46112
47- // Abort the transaction, discarding any data created as part of it
48- DB::rollBack();
113+ .. _laravel-transaction-commit:
49114
115+ Begin and Commit a Transaction
116+ ------------------------------
50117
51- .. note::
118+ This section shows how to start and commit a transaction.
52119
53- Transactions in MongoDB cannot be nested. DB::beginTransaction() function
54- will start new transactions in a new created or existing session and will
55- raise the RuntimeException when transactions already exist. See more in
56- MongoDB official docs :manual:`Transactions and Sessions </core/transactions/#transactions-and-sessions>` .
120+ To use this method of starting and committing a transaction, call the
121+ ``DB::beginTransaction()`` method to start the transaction. Then, call the
122+ ``DB::commit()`` method to end the transaction, which applies all the updates
123+ performed within the transaction .
57124
58- .. code-block:: php
125+ In the following example, the balance from the first account is moved to the
126+ second account, after which the first account is deleted:
59127
60- DB::beginTransaction();
61- User::create(['name' => 'john', 'age' => 20, 'title' => 'admin']);
128+ .. literalinclude:: /includes/fundamentals/transactions/TransactionsTest.php
129+ :language: php
130+ :dedent:
131+ :emphasize-lines: 1,9
132+ :start-after: begin commit transaction
133+ :end-before: end commit transaction
62134
63- // This call to start a nested transaction will raise a RuntimeException
64- DB::beginTransaction();
65- DB::collection('users')->where('name', 'john')->update(['age' => 20]);
66- DB::commit();
67- DB::rollBack();
135+ .. _laravel-transaction-rollback:
68136
69- Database Testing
70- ----------------
137+ Roll Back a Transaction
138+ -----------------------
71139
72- For testing, the traits ``Illuminate\Foundation\Testing\DatabaseTransactions``
73- and ``Illuminate\Foundation\Testing\RefreshDatabase`` are not yet supported.
74- Instead, create migrations and use the ``DatabaseMigrations`` trait to reset
75- the database after each test:
140+ This section shows how to roll back a transaction. A rollback reverts all the
141+ write operations performed within that transaction. This means that the
142+ data is reverted to its state before the transaction.
76143
77- .. code-block:: php
144+ To perform the rollback, call the ``DB::rollback()`` function anytime before
145+ the transaction is committed.
146+
147+ In the following example, the transaction consists of write operations that
148+ transfer funds from one account, represented by the ``Account`` model, to
149+ multiple other accounts. If the sender account has insufficient funds, the
150+ transaction is rolled back, and none of the models are updated:
151+
152+ .. literalinclude:: /includes/fundamentals/transactions/TransactionsTest.php
153+ :language: php
154+ :dedent:
155+ :emphasize-lines: 1,18,20
156+ :start-after: begin rollback transaction
157+ :end-before: end rollback transaction
78158
79- use Illuminate\Foundation\Testing\DatabaseMigrations;
0 commit comments