Skip to content
58 changes: 46 additions & 12 deletions source/sessions/snapshot-sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,24 +63,28 @@ response. The `atClusterTime` field represents the timestamp of the read and is
## Specification

An application requests snapshot reads by creating a `ClientSession` with options that specify that snapshot reads are
desired. An application then passes the session as an argument to methods in the `MongoDatabase` and `MongoCollection`
classes. Read operations (find/aggregate/distinct) performed against that session will be read from the same snapshot.
desired and optionally specifying a `snapshotTime`. An application then passes the session as an argument to methods in
the `MongoDatabase` and `MongoCollection` classes. Read operations (find/aggregate/distinct) performed against that
session will be read from the same snapshot.

## High level summary of the API changes for snapshot reads

Snapshot reads are built on top of client sessions.

Applications will start a new client session for snapshot reads like this:
Applications will start a new client session for snapshot reads and possibly retrieve the snapshot time like this:

```typescript
options = new SessionOptions(snapshot = true);
options = new SessionOptions(snapshot = true, snapshotTime = timestampValue);
session = client.startSession(options);
snapshotTime = session.snapshotTime;
```

All read operations performed using this session will be read from the same snapshot.

If no value is provided for `snapshot` a value of false is implied. There are no MongoDatabase, MongoClient, or
MongoCollection API changes.
If no value is provided for `snapshot` a value of false is implied. `snapshotTime` is an optional parameter and if not
passed the snapshot time will be set internally after the first find/aggregate/distinct operation inside the session.

There are no MongoDatabase, MongoClient, or MongoCollection API changes.

## SessionOptions changes

Expand All @@ -89,13 +93,15 @@ MongoCollection API changes.
```typescript
class SessionOptions {
Optional<bool> snapshot;
Optional<BsonTimestamp> snapshotTime;

// other options defined by other specs
}
```

In order to support snapshot reads a new property named `snapshot` is added to `SessionOptions`. Applications set
`snapshot` when starting a client session to indicate whether they want snapshot reads. All read operations performed
In order to support snapshot reads two properties called `snapshot` and `snapshotTime` are added to
`SessionOptions`. Applications set `snapshot` when starting a client session to indicate whether they want snapshot
reads and optionally set `snapshotTime` to specify the desired snapshot time beforehand. All read operations performed
using that client session will share the same snapshot.

Each new member is documented below.
Expand All @@ -110,11 +116,36 @@ Snapshot reads and causal consistency are mutually exclusive. Therefore if `snap
`causalConsistency` must be false. Client MUST throw an error if both `snapshot` and `causalConsistency` are set to
true. Snapshot reads are supported on both primaries and secondaries.

### snapshotTime

Applications set `snapshotTime` when starting a snapshot session to specify the desired snapshot time.

Note that the `snapshotTime` property is optional. The default value of this property is null.

Client MUST throw an error if `snapshotTime` is set and `snapshot` is not set to true.

Note that when parsing `snapshotTime` for [unified tests](https://github.com/mongodb/specifications/blob/master/source/unified-test-format/unified-test-format.md), the parsed string is the name of the key for the actual value of `snapshotTime` to be found in the [entity map](https://github.com/mongodb/specifications/blob/master/source/unified-test-format/unified-test-format.md#entity-map).

## ClientSession changes

A new readonly property called `snapshotTime` will be added to `ClientSession` that allows applications to retrieve the
snapshot time of the session:

```typescript
class ClientSession {
readonly Optional<BsonTimestamp> snapshotTime;

// other options defined by other specs
}
```

Getting the value of `snapshotTime` on a non-snapshot session MUST raise an error.

Transactions are not allowed with snapshot sessions. Calling `session.startTransaction(options)` on a snapshot session
MUST raise an error.

Note that a new operation on session called `getSnapshotTime` must be supported for [unified tests](https://github.com/mongodb/specifications/blob/master/source/unified-test-format/unified-test-format.md). This operation returns the value of `snapshotTime` on the session, so that it can be used in following operations.

## ReadConcern changes

`snapshot` added to [ReadConcernLevel enumeration](../read-write-concern/read-write-concern.md#read-concern).
Expand All @@ -123,10 +154,12 @@ MUST raise an error.

There are no new server commands related to snapshot reads. Instead, snapshot reads are implemented by:

1. Saving the `atClusterTime` returned by 5.0+ servers for the first find/aggregate/distinct operation in a private
`snapshotTime` property of the `ClientSession` object. Drivers MUST save `atClusterTime` in the `ClientSession`
object.
2. Passing that `snapshotTime` in the `atClusterTime` field of the `readConcern` field for subsequent snapshot read
1. If `snapshotTime` is specified in `SessionOptions`, saving the value in a `snapshotTime` property of the
`ClientSession`.
2. If `snapshotTime` is not specified in `SessionOptions`, saving the `atClusterTime` returned by 5.0+ servers for the
first find/aggregate/distinct operation in a `snapshotTime` property of the `ClientSession` object. Drivers
MUST save `atClusterTime` in the `ClientSession` object.
3. Passing that `snapshotTime` in the `atClusterTime` field of the `readConcern` field for subsequent snapshot read
operations (i.e. find/aggregate/distinct commands).

## Server Command Responses
Expand Down Expand Up @@ -241,6 +274,7 @@ C# driver will provide the reference implementation. The corresponding ticket is

## Changelog

- 2025-09-23: Exposed snapshotTime to applications.
- 2024-05-08: Migrated from reStructuredText to Markdown.
- 2021-06-15: Initial version.
- 2021-06-28: Raise client side error on < 5.0.
Expand Down
8 changes: 8 additions & 0 deletions source/sessions/tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,16 @@ and configure a `MongoClient` with default options.
- Run a ping command using C1 and assert that `$clusterTime` sent is the same as the `clusterTime` recorded earlier.
This assertion proves that C1's `$clusterTime` was not advanced by gossiping through SDAM.

### 21. Having `snapshotTime` set and `snapshot` set to false is not allowed

Snapshot sessions tests require server of version 5.0 or higher and replica set or a sharded cluster deployment.

- `client.startSession(snapshot = false, snapshotTime = new Timestamp(1))`
- Assert that an error was raised by driver

## Changelog

- 2025-09-25: Added test for snapshotTime.
- 2025-02-24: Test drivers do not gossip $clusterTime on SDAM.
- 2024-05-08: Migrated from reStructuredText to Markdown.
- 2019-05-15: Initial version.
Expand Down
Loading
Loading