Docs Menu
Docs Home
/ / /
Ruby Driver
/

Transactions

In this guide, you can learn how to use the Ruby driver to perform transactions. Transactions allow you to perform a series of operations that change data only if the entire transaction is committed. If any operation in the transaction does not succeed, the driver stops the transaction and discards all data changes before they ever become visible. This feature is called atomicity.

In MongoDB, transactions run within logical sessions. A session is a grouping of related read or write operations that you want to run sequentially. Sessions enable causal consistency for a group of operations and allow you to run operations in an ACID-compliant transaction, which is a transaction that meets an expectation of atomicity, consistency, isolation, and durability. MongoDB guarantees that the data involved in your transaction operations remains consistent, even if the operations encounter unexpected errors.

When using the Ruby driver, you can start a session by calling the start_session method on your client. Then, you can perform transactions within the session.

Warning

Use a session only in operations running on the Mongo::Client that created it. Using a session with a different Mongo::Client results in operation errors.

MongoDB enables causal consistency in certain client sessions. The causal consistency model guarantees that in a distributed system, operations within a session run in a causal order. Clients observe results that are consistent with the causal relationships, or the dependencies between operations. For example, if you perform a series of operations where one operation logically depends on the result of another, any subsequent reads reflect the dependent relationship.

To guarantee causal consistency, client sessions must fulfill the following requirements:

  • When starting a session, the driver must enable the causal consistency option. This option is enabled by default.

  • Operations must run in a single session on a single thread. Otherwise, the sessions or threads must communicate the operation time and cluster time values to each other. To view an example of two sessions that communicate these values, see the Causal Consistency examples in the MongoDB Server manual.

  • You must use a :majority read concern.

  • You must use a :majority write concern. This is the default write concern value.

The following table describes the guarantees that causally consistent sessions provide:

Guarantee
Description

Read your writes

Read operations reflect the results of preceding write operations.

Monotonic reads

Read operations do not return results that reflect an earlier data state than a preceding read operation.

Monotonic writes

If a write operation must precede other write operations, the server runs this write operation first.

For example, if you call insert_one() to insert a document, then call update_one() to modify the inserted document, the server runs the insert operation first.

Writes follow reads

If a write operation must follow other read operations, the server runs the read operations first.

For example, if you call find() to retrieve a document, then call delete_one() to delete the retrieved document, the server runs the find operation first.

Tip

To learn more about the concepts mentioned in this section, see the following MongoDB Server manual entries:

After calling the start_session method to start a session, you can use methods from the Mongo::Session class to manage the session state. The following table describes the methods you can use to manage a transaction:

Method
Description

start_transaction

Starts a new transaction on this session. You cannot start a transaction if there's already an active transaction running in the session.

You can set transaction options including read concern, write concern, and read preference by passing a Hash as a parameter.

commit_transaction

Commits the active transaction for this session. This method returns an error if there is no active transaction for the session, the transaction was previously ended, or if there is a write conflict.

abort_transaction

Ends the active transaction for this session. This method returns an error if there is no active transaction for the session or if the transaction was committed or ended.

with_transaction

Starts a transaction prior to calling the supplied block, and commits the transaction when the block finishes. If any of the operations in the block, or the commit operation, result in a transient transaction error, the block and/or the commit will be executed again.

This example defines a run_transaction method that modifies data in the collections of the sample_mflix database. The code performs the following actions:

  • Creates Mongo::Collection instances to access the movies and users collections.

  • Specifies the read and write concerns for the transaction.

  • Starts the transaction.

  • Inserts a document into the movies collection and prints the results.

  • Updates a document in the users collection and prints the results.

database = client.use('sample_mflix')
movies_collection = database[:movies]
users_collection = database[:users]
def run_transaction(session, movies_collection, users_collection)
transaction_options = {
read_concern: { level: "snapshot" },
write_concern: { w: "majority" }
}
session.with_transaction(transaction_options) do
# Inserts document into the "movies" collection
insert_result = movies_collection.insert_one({ name: 'The Menu', runtime: 107 }, session: session)
puts "Insert completed: #{insert_result.inspect}"
# Updates document in the "users" collection
update_result = users_collection.update_one({ name: 'Amy Phillips'}, { "$set" => { name: 'Amy Ryan' }}, session: session)
puts "Update completed: #{update_result.inspect}"
end
end
# Starts a session
session = client.start_session
begin
# Runs the transaction
run_transaction(session, movies_collection, users_collection)
puts "Transaction committed successfully."
rescue Mongo::Error::OperationFailure => e
puts "Transaction failed and was aborted. Error: #{e.message}"
ensure
session.end_session
end

Note

Parallel Operations Not Supported

The Ruby driver does not support running parallel operations within a single transaction.

If you're using MongoDB Server v8.0 or later, you can perform write operations on multiple namespaces within a single transaction by using the bulk_write method. For more information, see the Bulk Write Operations guide.

To learn more about the concepts mentioned in this guide, see the following pages in the MongoDB Server manual:

To learn more about ACID compliance, see the A Guide to ACID Properties in Database Management Systems article on the MongoDB website.

To learn more about insert operations, see the Insert Documents guide.

To learn more about the methods and types mentioned in this guide, see the following API documentation:

Back

Bulk Write Operations

On this page