Version 3.6 of the MongoDB server introduces the concept of logical sessions for clients. A session is an abstract concept that represents a set of sequential operations executed by an application that are related in some way. A session object can be created via a Mongo::Client and passed to operation methods that should be executed in the context of that session.

Please note that session objects are not thread safe. They must only be used by one thread at a time.

Creating a session from a Mongo::Client

A session can be created by calling the start_session method on a client:

session = client.start_session

It is valid to call start_session with no options set. This will result in a session that has no effect on the operations performed in the context of that session, other than to include a session ID in commands sent to the server. Please see the API docs for all supported session options.

An error will be thrown if the driver is connected to a deployment that does not support sessions and the start_session method is called.

Note that server sessions are discarded server-side if not used for a certain period of time. Be aware that if the application calls #start_session on a client and waits more than 1 minute to use the session, it risks getting errors due to the session going stale before it is used.

Using a session

A session object can be passed to most driver methods so that the operation can be executed in the context of that session. Please see the API docs for which methods support a session argument.

Create a session and execute an insert, then a find using that session:

session = client.start_session
client[:artists].insert_one({ :name => 'FKA Twigs' }, session: session)
client[:artists].find({ :name => 'FKA Twigs' }, limit: 1, session: session).first

If you like to call methods on a Mongo::Collection::View in the context of a particular session, you can create the Mongo::Collection::View with the session and then call methods on it:

session = client.start_session(causal_consistency: true)
view = client[:artists].find({ :name => 'FKA Twigs' }, session: session)
view.count # will use the session

You can also pass the session option to the methods directly. This session will override any session associated with the Mongo::Collection::View:

session = client.start_session
second_session = client.start_session
view = client[:artists].find({ :name => 'FKA Twigs' }, session: session)
view.count(session: second_session) # will use the second_session

Unacknowledged Writes

Unacknowledged writes are only allowed outside the session mechanism; if an explicit session is supplied for an unacknowledged write, the driver will not send the session id with the operation. Similarly, the driver will not use an implicit session for an unacknowledged write.

Causal Consistency

A causally consistent session will let you read your writes and guarantee monotonically increasing reads from secondaries. To create a causally consistent session, set the causal_consistency option to true:

session = client.start_session(causal_consistency: true)

# The update message goes to the primary.
collection = client[:artists]
collection.update_one({ '_id' => 1 }, { '$set' => { 'x' => 0 } }, session: session)

# Read your write, even when reading from a secondary!
collection.find({ '_id' => 1 }, session: session).first

# This query returns data at least as new as the previous query,
# even if it chooses a different secondary.
collection.find({ '_id' => 2 }, session: session).first

Since unacknowledged writes don’t receive a response from the server (or don’t wait for a response), the driver has no way of keeping track of where the unacknowledged write is in logical time. Therefore, causally consistent reads are not causally consistent with unacknowledged writes.

Note that if you set the causal_consistency option to nil as in (causal_consistency: nil), it will be interpreted as false.

End a session

To end a session, call the end_session method:


The Ruby driver will then add the id for the corresponding server session to a pool for reuse. When a client is closed, the driver will send a command to the server to end all sessions it has cached in its server session pool. You may see this command in your logs when a client is closed.

←   Projections Transactions  →