Skip to content

feat(mongodb): make transaction read concern configurable - #314

Open
xgerman wants to merge 4 commits into
ExtendDB:mainfrom
xgerman:geeichbe/configurable-transaction-read-concern
Open

feat(mongodb): make transaction read concern configurable#314
xgerman wants to merge 4 commits into
ExtendDB:mainfrom
xgerman:geeichbe/configurable-transaction-read-concern

Conversation

@xgerman

@xgerman xgerman commented Aug 26, 2026

Copy link
Copy Markdown

Problem

The MongoDB storage backend hardcodes readConcern: snapshot on every multi-document transaction it opens (conditional writes, TransactWriteItems, TransactGetItems, idempotency-token checks). Real MongoDB (7.0+) supports this and it's the strongest available isolation level, but some MongoDB-wire-compatible servers do not implement it.

Concretely, DocumentDB (a Postgres-based MongoDB-API-compatible database) rejects transactions started with readConcern: snapshot with Error code 115 (CommandNotSupported), which makes the mongodb backend unusable against it beyond CreateTable.

Change

Adds storage.mongodb.transaction_read_concern (default: "snapshot", preserving current behavior) so operators can set "majority" or "local" to run against backends that don't implement snapshot reads, trading off snapshot isolation for compatibility. Also updates the MongoDB backend design doc (docs/design/13-storage-mongodb.md) to describe the new setting.

As a side effect, this widens ServerComponentsFactory's StorageConfig trait-object bound from an elided reference lifetime to 'static. StorageConfig::as_any()'s downcast is already documented as the intended mechanism for backend-specific settings like this one, but Any::downcast_ref requires the pointee to be provably 'static — an unannotated &dyn StorageConfig doesn't satisfy that, so the downcast wouldn't compile without this change. All existing callers already own 'static data (Box<dyn StorageConfig>), so this is not a breaking change for callers.

Validation

  • cargo build --workspace, cargo test (all touched crates pass), cargo clippy --workspace -- -D warnings clean.
  • Verified end-to-end against a real DocumentDB 0.116.0 instance (built from source to pick up an unrelated upstream Postgres-extension fix) with transaction_read_concern = "majority": CreateTable, PutItem, GetItem, and DeleteTable all succeeded via the DynamoDB API surface.
  • Default behavior (real MongoDB, transaction_read_concern unset) is unchanged — still snapshot.

Trade-offs

Running with majority/local instead of snapshot weakens isolation between concurrent transactions on backends that use this setting — concurrent transactions may observe a less consistent view of the data than under true snapshot reads. This is called out in both the sample config and the design doc.

German and others added 2 commits August 25, 2026 17:11
The MongoDB storage backend hardcodes readConcern: snapshot on every
multi-document transaction (conditional writes, TransactWriteItems,
TransactGetItems, idempotency tokens). Real MongoDB (7.0+) supports this,
but some MongoDB-wire-compatible servers do not.

Concretely, DocumentDB (github.com/documentdb/documentdb) rejects
transactions started with readConcern: snapshot with
'Error code 115 (CommandNotSupported)', which made the mongodb backend
unusable against it beyond CreateTable.

Add storage.mongodb.transaction_read_concern (default: "snapshot",
preserving current behavior) so operators can set "majority" or
"local" to run against backends that don't implement snapshot reads,
trading off snapshot isolation for compatibility. Validated end-to-end
against DocumentDB 0.116.0 (PutItem/GetItem/CreateTable/DeleteTable all
succeed with transaction_read_concern = "majority").

Also widens the StorageConfig trait-object bound used by
ServerComponentsFactory from an elided reference lifetime to
'static, since StorageConfig::as_any()'s downcast (already
documented as intended for backend-specific settings like this one)
requires it -- without it, Any::downcast_ref cannot be proven sound
against an unannotated &dyn StorageConfig.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1de8a53e-4145-4deb-8d82-294a4879046e
Signed-off-by: German <geeichbe@microsoft.com>
Updates the MongoDB backend design doc (13-storage-mongodb.md) to
reflect that transaction read concern is now configurable via
storage.mongodb.transaction_read_concern, rather than unconditionally
snapshot. Left the RFC (docs/rfcs/0000-mongodb-backend.md) as a
point-in-time design record, matching this repo's convention for RFCs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1de8a53e-4145-4deb-8d82-294a4879046e
Signed-off-by: German <geeichbe@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant