- Working With Data >
- Transactions
Transactions¶
On this page
Version 4.0 of the MongoDB server introduces multi-document transactions. (Updates to multiple fields within a single document are atomic in all versions of MongoDB). Transactions require a non-standalone MongoDB topology and Ruby driver version 2.6 or higher. A higher level transaction API requires Mongoid version 9.0 or higher, while a lower level API requires Mongoid version 6.4 or higher.
Using Transactions¶
Higher Level API¶
A transaction can be started by calling the transaction
method on an instance
of a Mongoid document class, on a Mongoid document class, on or Mongoid
module:
When the transaction
method is called, Mongoid does the following:
- creates a session on a client that is used by the receiver of the
transaction
method call; - starts a transaction on the session;
- executes the given block;
- commits the transaction if no exception raised in the block;
- calls
after_commit
callbacks for all objects modified inside the transaction
- calls
- aborts the transaction if an exception is raised in the block;
- calls
after_rollback
callbacks for all objects modified inside the transaction
- calls
- closes the session
Note
Since a transaction is tied to a particular client, _only_ operations on
the same client will be in scope of the transaction. Therefore it
is recommended that only objects that use the same client are used inside the
transaction
method block.
Note
When transaction
method is called on Mongoid
module, the transaction
is created using the :default
client.
Aborting Transaction¶
Any exception raised inside the transaction
method block aborts the
transaction. Normally the raised exception passed on, except for the
Mongoid::Errors::Rollback
. This error should be raised if you want to
explicitly abort the transaction without passing on an exception.
Callbacks¶
Transaction API introduces two new callbacks - after_commit
and after_rollback
.
after_commit
callback is triggered for an object that was created, saved,
or destroyed:
- after transaction is committed if the object was modified inside the transaction;
- after the object was persisted if the object was modified outside a transaction.
Note
In any case after_commit
callback is triggered only after all other callbacks
were executed successfully. Therefore, if the object is modified without a
transaction, it is possible that the object was persisted, but after_commit
callback was not triggered (for example, an exception raised in after_save
callback).
after_rollback
callback is triggered for an object that was created, saved,
or destroyed inside a transaction if the transaction was aborted. after_rollback
is never triggered without a transaction.
Lower Level API¶
In order to start a transaction, the application must have a session.
A transaction can be started by calling the start_transaction
method on a session, which can be
obtained by calling the with_session
method on either a model class or instance:
It is also possible to specify read concern, write concern and read preference when starting a transaction:
A transaction may be committed or aborted. The corresponding methods to do so are
commit_transaction
and abort_transaction
, again on the session instance:
If a session ends with an open transaction, the transaction is aborted.
The transaction commit can be retried if it fails. Here is the Ruby code to do so:
Note that in order to perform operations within the transaction, operations must use the same client that the session was initiated on. By default, all operations will be done on the default client:
To explicitly use a different client, use the with
method: