Skip to content

Distributed / multi-document transaction support#327

Open
hatspencer wants to merge 14 commits into
vert-x3:masterfrom
ferakpeter:distributed-transaction-support
Open

Distributed / multi-document transaction support#327
hatspencer wants to merge 14 commits into
vert-x3:masterfrom
ferakpeter:distributed-transaction-support

Conversation

@hatspencer

@hatspencer hatspencer commented Nov 21, 2025

Copy link
Copy Markdown

Motivation:

MongoDB supports distributed transactions since version 4.2, and this has been also available on the driver level for a while. The goal of this PR is to add API support for such distributed / multi document transactions.

Related issues: #242, #158

The newly defined MongoSession is a wrapper implementation around MongoClient but with the added control for start/commit/abort.

Usage examples:

MongoClient#executeTransaction() - compose and execute the provided future in transaction, commit on success, abort on failure automatically using handlers.

public void executeTransactionExample(MongoClient mongoClient) {
  // Match any documents with title=The Hobbit
  JsonObject query = new JsonObject()
    .put("title", "The Hobbit");
  // Set the author field
  JsonObject update = new JsonObject().put("$set", new JsonObject()
    .put("author", "J. R. R. Tolkien"));
  UpdateOptions options = new UpdateOptions().setMulti(true);

  mongoClient.executeTransaction(client -> Future.join(
      client.updateCollectionWithOptions("books", query, update, options),
      client.insert("authors", update)
    ))
    .onFailure(throwable -> System.err.println(throwable.getMessage()))
    .onComplete(res -> {
      if (res.succeeded()) {
        System.out.println("Book and Author updated !");
      } else {
        res.cause().printStackTrace();
      }
    });
}

MongoClient#startSession() - allows for manual control of commit / abort.

public void startSessionExample(MongoClient mongoClient) {
  mongoClient.startSession()
    .flatMap(session -> {
      // Match any documents with title=The Hobbit
      JsonObject query = new JsonObject()
        .put("title", "The Hobbit");
      // Set the author field
      JsonObject update = new JsonObject().put("$set", new JsonObject()
        .put("author", "J. R. R. Tolkien"));
      UpdateOptions options = new UpdateOptions().setMulti(true);

      return session.executeTransaction(client -> Future.join(
        client.updateCollectionWithOptions("books", query, update, options),
        client.insert("authors", update))
      );
    })
    .onFailure(throwable -> System.err.println(throwable.getMessage()))
    .onComplete(res -> {
      if (res.succeeded()) {
        System.out.println("Book and Author updated !");
      } else {
        res.cause().printStackTrace();
      }
    });
}

By default, the underlying session is started with a transaction and closed automatically after commit or abort. The client session's behaviour can be changed by passing a ClientSessionOptions instance. For example:

mongoClient.startSession(new ClientSessionOptions().setCloseSession(false))

@hatspencer
hatspencer marked this pull request as draft November 22, 2025 17:20
@hatspencer
hatspencer marked this pull request as ready for review November 24, 2025 08:12
@vietj vietj added this to the 5.1.0 milestone Nov 28, 2025
ferakpeter and others added 2 commits November 28, 2025 18:07
- propagate session also for reads
- extend tests and examples
@vietj vietj modified the milestones: 5.1.0, 5.1.1, 5.1.2 May 31, 2026
@vietj vietj modified the milestones: 5.1.2, 5.1.3 Jun 8, 2026
@vietj vietj modified the milestones: 5.1.3, 5.1.4 Jun 23, 2026
@vietj vietj modified the milestones: 5.1.4, 5.1.5, 5.1.6 Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants