client_session – Logical sessions for sequential operations#

Logical sessions for ordering sequential operations.

New in version 3.6.

Causally Consistent Reads#

with client.start_session(causal_consistency=True) as session:
    collection = client.db.collection
    collection.update_one({"_id": 1}, {"$set": {"x": 10}}, session=session)
    secondary_c = collection.with_options(read_preference=ReadPreference.SECONDARY)

    # A secondary read waits for replication of the write.
    secondary_c.find_one({"_id": 1}, session=session)

If causal_consistency is True (the default), read operations that use the session are causally after previous read and write operations. Using a causally consistent session, an application can read its own writes and is guaranteed monotonic reads, even when reading from replica set secondaries.

See also

The MongoDB documentation on causal-consistency.

Transactions#

New in version 3.7.

MongoDB 4.0 adds support for transactions on replica set primaries. A transaction is associated with a ClientSession. To start a transaction on a session, use ClientSession.start_transaction() in a with-statement. Then, execute an operation within the transaction by passing the session to the operation:

orders = client.db.orders
inventory = client.db.inventory
with client.start_session() as session:
    with session.start_transaction():
        orders.insert_one({"sku": "abc123", "qty": 100}, session=session)
        inventory.update_one(
            {"sku": "abc123", "qty": {"$gte": 100}},
            {"$inc": {"qty": -100}},
            session=session,
        )

Upon normal completion of with session.start_transaction() block, the transaction automatically calls ClientSession.commit_transaction(). If the block exits with an exception, the transaction automatically calls ClientSession.abort_transaction().

In general, multi-document transactions only support read/write (CRUD) operations on existing collections. However, MongoDB 4.4 adds support for creating collections and indexes with some limitations, including an insert operation that would result in the creation of a new collection. For a complete description of all the supported and unsupported operations see the MongoDB server’s documentation for transactions.

A session may only have a single active transaction at a time, multiple transactions on the same session can be executed in sequence.

Sharded Transactions#

New in version 3.9.

PyMongo 3.9 adds support for transactions on sharded clusters running MongoDB >=4.2. Sharded transactions have the same API as replica set transactions. When running a transaction against a sharded cluster, the session is pinned to the mongos server selected for the first operation in the transaction. All subsequent operations that are part of the same transaction are routed to the same mongos server. When the transaction is completed, by running either commitTransaction or abortTransaction, the session is unpinned.

See also

The MongoDB documentation on transactions.

Snapshot Reads#

New in version 3.12.

MongoDB 5.0 adds support for snapshot reads. Snapshot reads are requested by passing the snapshot option to start_session(). If snapshot is True, all read operations that use this session read data from the same snapshot timestamp. The server chooses the latest majority-committed snapshot timestamp when executing the first read operation using the session. Subsequent reads on this session read from the same snapshot timestamp. Snapshot reads are also supported when reading from replica set secondaries.

# Each read using this session reads data from the same point in time.
with client.start_session(snapshot=True) as session:
    order = orders.find_one({"sku": "abc123"}, session=session)
    inventory = inventory.find_one({"sku": "abc123"}, session=session)

Snapshot Reads Limitations#

Snapshot reads sessions are incompatible with causal_consistency=True. Only the following read operations are supported in a snapshot reads session:

Classes#

class pymongo.client_session.ClientSession(client, server_session, options, implicit)#

A session for ordering sequential operations.

ClientSession instances are not thread-safe or fork-safe. They can only be used by one thread or process at a time. A single ClientSession cannot be used to run multiple operations concurrently.

Should not be initialized directly by application developers - to create a ClientSession, call start_session().

Parameters:
abort_transaction()#

Abort a multi-statement transaction.

New in version 3.7.

Return type:

None

advance_cluster_time(cluster_time)#

Update the cluster time for this session.

Parameters:

cluster_time (Mapping[str, Any]) – The cluster_time from another ClientSession instance.

Return type:

None

advance_operation_time(operation_time)#

Update the operation time for this session.

Parameters:

operation_time (Timestamp) – The operation_time from another ClientSession instance.

Return type:

None

property client: MongoClient#

The MongoClient this session was created from.

property cluster_time: ClusterTime | None#

The cluster time returned by the last operation executed in this session.

commit_transaction()#

Commit a multi-statement transaction.

New in version 3.7.

Return type:

None

end_session()#

Finish this session. If a transaction has started, abort it.

It is an error to use the session after the session has ended.

Return type:

None

property has_ended: bool#

True if this session is finished.

property in_transaction: bool#

True if this session has an active multi-statement transaction.

New in version 3.10.

property operation_time: Timestamp | None#

The operation time returned by the last operation executed in this session.

property options: SessionOptions#

The SessionOptions this session was created with.

property session_id: Mapping[str, Any]#

A BSON document, the opaque server session identifier.

start_transaction(read_concern=None, write_concern=None, read_preference=None, max_commit_time_ms=None)#

Start a multi-statement transaction.

Takes the same arguments as TransactionOptions.

Changed in version 3.9: Added the max_commit_time_ms option.

New in version 3.7.

Parameters:
  • read_concern (ReadConcern | None) –

  • write_concern (WriteConcern | None) –

  • read_preference (_ServerMode | None) –

  • max_commit_time_ms (int | None) –

Return type:

ContextManager

with_transaction(callback, read_concern=None, write_concern=None, read_preference=None, max_commit_time_ms=None)#

Execute a callback in a transaction.

This method starts a transaction on this session, executes callback once, and then commits the transaction. For example:

def callback(session):
    orders = session.client.db.orders
    inventory = session.client.db.inventory
    orders.insert_one({"sku": "abc123", "qty": 100}, session=session)
    inventory.update_one({"sku": "abc123", "qty": {"$gte": 100}},
                         {"$inc": {"qty": -100}}, session=session)

with client.start_session() as session:
    session.with_transaction(callback)

To pass arbitrary arguments to the callback, wrap your callable with a lambda like this:

def callback(session, custom_arg, custom_kwarg=None):
    # Transaction operations...

with client.start_session() as session:
    session.with_transaction(
        lambda s: callback(s, "custom_arg", custom_kwarg=1))

In the event of an exception, with_transaction may retry the commit or the entire transaction, therefore callback may be invoked multiple times by a single call to with_transaction. Developers should be mindful of this possibility when writing a callback that modifies application state or has any other side-effects. Note that even when the callback is invoked multiple times, with_transaction ensures that the transaction will be committed at-most-once on the server.

The callback should not attempt to start new transactions, but should simply run operations meant to be contained within a transaction. The callback should also not commit the transaction; this is handled automatically by with_transaction. If the callback does commit or abort the transaction without error, however, with_transaction will return without taking further action.

ClientSession instances are not thread-safe or fork-safe. Consequently, the callback must not attempt to execute multiple operations concurrently.

When callback raises an exception, with_transaction automatically aborts the current transaction. When callback or commit_transaction() raises an exception that includes the "TransientTransactionError" error label, with_transaction starts a new transaction and re-executes the callback.

When commit_transaction() raises an exception with the "UnknownTransactionCommitResult" error label, with_transaction retries the commit until the result of the transaction is known.

This method will cease retrying after 120 seconds has elapsed. This timeout is not configurable and any exception raised by the callback or by ClientSession.commit_transaction() after the timeout is reached will be re-raised. Applications that desire a different timeout duration should not use this method.

Parameters:
  • callback (Callable[[ClientSession], _T]) – The callable callback to run inside a transaction. The callable must accept a single argument, this session. Note, under certain error conditions the callback may be run multiple times.

  • read_concern (ReadConcern | None) – The ReadConcern to use for this transaction.

  • write_concern (WriteConcern | None) – The WriteConcern to use for this transaction.

  • read_preference (_ServerMode | None) – The read preference to use for this transaction. If None (the default) the read_preference of this Database is used. See read_preferences for options.

  • max_commit_time_ms (int | None) –

Returns:

The return value of the callback.

Return type:

_T

New in version 3.9.

class pymongo.client_session.SessionOptions(causal_consistency=None, default_transaction_options=None, snapshot=False)#

Options for a new ClientSession.

Parameters:
  • causal_consistency (Optional[bool]) – If True, read operations are causally ordered within the session. Defaults to True when the snapshot option is False.

  • default_transaction_options (Optional[TransactionOptions]) – The default TransactionOptions to use for transactions started on this session.

  • snapshot (Optional[bool]) – If True, then all reads performed using this session will read from the same snapshot. This option is incompatible with causal_consistency=True. Defaults to False.

Changed in version 3.12: Added the snapshot parameter.

property causal_consistency: bool#

Whether causal consistency is configured.

property default_transaction_options: TransactionOptions | None#

The default TransactionOptions to use for transactions started on this session.

New in version 3.7.

property snapshot: bool | None#

Whether snapshot reads are configured.

New in version 3.12.

class pymongo.client_session.TransactionOptions(read_concern=None, write_concern=None, read_preference=None, max_commit_time_ms=None)#

Options for ClientSession.start_transaction().

Parameters:
  • read_concern (Optional[ReadConcern]) – The ReadConcern to use for this transaction. If None (the default) the read_preference of the MongoClient is used.

  • write_concern (Optional[WriteConcern]) – The WriteConcern to use for this transaction. If None (the default) the read_preference of the MongoClient is used.

  • read_preference (Optional[_ServerMode]) – The read preference to use. If None (the default) the read_preference of this MongoClient is used. See read_preferences for options. Transactions which read must use PRIMARY.

  • max_commit_time_ms (Optional[int]) – The maximum amount of time to allow a single commitTransaction command to run. This option is an alias for maxTimeMS option on the commitTransaction command. If None (the default) maxTimeMS is not used.

Changed in version 3.9: Added the max_commit_time_ms option.

New in version 3.7.

property max_commit_time_ms: int | None#

The maxTimeMS to use when running a commitTransaction command.

New in version 3.9.

property read_concern: ReadConcern | None#

This transaction’s ReadConcern.

property read_preference: _ServerMode | None#

This transaction’s ReadPreference.

property write_concern: WriteConcern | None#

This transaction’s WriteConcern.