You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ke...@apache.org on 2026/04/01 00:29:48 UTC

(tinkerpop) branch master updated: Update HTTP remote transactions documentation CTR

This is an automated email from the ASF dual-hosted git repository.

kenhuuu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/master by this push:
     new 2ea8ad05f8 Update HTTP remote transactions documentation CTR
2ea8ad05f8 is described below

commit 2ea8ad05f874f9e390e5ab2674d6a428b27fd432
Author: Ken Hu <10...@users.noreply.github.com>
AuthorDate: Tue Mar 31 16:50:30 2026 -0700

    Update HTTP remote transactions documentation CTR
---
 docs/src/reference/gremlin-applications.asciidoc |   4 +-
 docs/src/reference/gremlin-variants.asciidoc     | 132 +++++++++++++----------
 docs/src/reference/the-traversal.asciidoc        |  83 ++++++++------
 3 files changed, 128 insertions(+), 91 deletions(-)

diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 1d124c1e22..b65b9c58ee 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -813,10 +813,11 @@ The following table describes the various YAML configuration options that Gremli
 |keepAliveInterval |Time in milliseconds that the server will allow a channel to not send responses to a client before it sends a "ping" to see if it is still present. If it is present, the client should respond with a "pong" which will thus reset the `idleConnectionTimeout` and keep the channel open. If enabled, this number should be smaller than the value provided to the `idleConnectionTimeout`. Note that while this value is to be provided as milliseconds it will resolve to second prec [...]
 |maxAccumulationBufferComponents |Maximum number of request components that can be aggregated for a message. |1024
 |maxChunkSize |The maximum length of the content or each chunk.  If the content length exceeds this value, the transfer encoding of the decoded request will be converted to 'chunked' and the content will be split into multiple `HttpContent` objects.  If the transfer encoding of the HTTP request is 'chunked' already, each chunk will be split into smaller chunks if the length of the chunk exceeds this value. |8192
-|maxRequestContentLength |The maximum length of the aggregated content for a request message.  Works in concert with `maxChunkSize` where chunked requests are accumulated back into a single message.  A request exceeding this size will return a `413 - Request Entity Too Large` status code. |10485760
+|maxConcurrentTransactions |The maximum number of concurrent open transactions allowed. When this limit is reached, new `g.tx().begin()` requests are rejected with HTTP 503. Slots are freed when transactions close via commit, rollback, or timeout. |1000
 |maxHeaderSize |The maximum length of all headers. |8192
 |maxInitialLineLength |The maximum length of the initial line (e.g.  "GET / HTTP/1.0") processed in a request, which essentially controls the maximum length of the submitted URI. |4096
 |maxParameters |The maximum number of parameters that can be passed on a request. Larger numbers may impact performance for scripts. This configuration only applies to the `HttpChannelizer`. |16
+|maxRequestContentLength |The maximum length of the aggregated content for a request message.  Works in concert with `maxChunkSize` where chunked requests are accumulated back into a single message.  A request exceeding this size will return a `413 - Request Entity Too Large` status code. |10485760
 |maxWorkQueueSize |The maximum size the general processing queue can grow before the `gremlinPool` starts to reject requests. |8192
 |metrics.consoleReporter.enabled |Turns on console reporting of metrics. |false
 |metrics.consoleReporter.interval |Time in milliseconds between reports of metrics to console. |180000
@@ -859,6 +860,7 @@ The following table describes the various YAML configuration options that Gremli
 |strictTransactionManagement |Set to `true` to require `aliases` to be submitted on every requests, where the `aliases` become the scope of transaction management. |false
 |threadPoolBoss |The number of threads available to Gremlin Server for accepting connections. Should always be set to `1`. |1
 |threadPoolWorker |The number of threads available to Gremlin Server for processing non-blocking reads and writes. |1
+|transactionTimeout |Time in milliseconds that a transaction can sit idle (no requests) before the server forcibly rolls it back and removes it. The timeout resets on each request received for that transaction. Set to `0` to disable this feature. |600000
 |useEpollEventLoop |Try to use epoll event loops (works only on Linux os) instead of netty NIO. |false
 |writeBufferHighWaterMark | If the number of bytes in the network send buffer exceeds this value then the channel is no longer writeable, accepting no additional writes until buffer is drained and the `writeBufferLowWaterMark` is met. |65536
 |writeBufferLowWaterMark | Once the number of bytes queued in the network send buffer exceeds the `writeBufferHighWaterMark`, the channel will not become writeable again until the buffer is drained and it drops below this value. |32768
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index 89cd8d63d4..b7561f313f 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -236,8 +236,8 @@ re-construction machine-side.
 [[gremlin-go-transactions]]
 === Transactions
 
-IMPORTANT: Transaction support over HTTP is not yet implemented in Gremlin-Go. This will be addressed in a future
-release.
+IMPORTANT: Transaction support over HTTP is not yet implemented in Gremlin-Go. This will be addressed by the official
+4.0.0 release.
 
 [[gremlin-go-gvalue]]
 === GValue Parameterization
@@ -839,7 +839,72 @@ Please see the link:https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/
 [[gremlin-java-transactions]]
 === Transactions
 
-IMPORTANT: 4.0.0-beta.1 Release - Transactions with Java aren't currently supported.
+Gremlin-Java supports remote transactions over HTTP. There are two ways to create a transaction: from a
+`GraphTraversalSource` or directly from a `Cluster` instance.
+
+==== Via GraphTraversalSource
+
+The recommended approach uses the standard `g.tx()` pattern:
+
+[source,java]
+----
+GraphTraversalSource g = traversal().with(DriverRemoteConnection.using("localhost", 8182, "g"));
+
+Transaction tx = g.tx();
+GraphTraversalSource gtx = tx.begin();
+
+try {
+    gtx.addV("person").property("name", "jorge").iterate();
+    gtx.addV("person").property("name", "josh").iterate();
+    tx.commit();
+} catch (Exception ex) {
+    tx.rollback();
+}
+----
+
+Traversals spawned from `gtx` are bound to the transaction. The driver handles host pinning and transaction ID
+propagation automatically.
+
+==== Via Cluster
+
+For script-based usage or when working with the `Client` API directly, transactions can be created from the `Cluster`:
+
+[source,java]
+----
+Cluster cluster = Cluster.build("localhost").create();
+RemoteTransaction tx = cluster.transact("g");
+tx.begin();
+
+try {
+    tx.submit("g.addV('person').property('name','alice')");
+    tx.submit("g.addV('person').property('name','bob')");
+    tx.commit();
+} catch (Exception ex) {
+    tx.rollback();
+}
+
+cluster.close();
+----
+
+The `RemoteTransaction` returned by `cluster.transact()` provides `submit()` methods that accept Gremlin strings
+and optional `RequestOptions` or parameter maps. All requests are pinned to a single host and include the transaction
+ID automatically.
+
+NOTE: `RemoteTransaction` is synchronous and not thread-safe. All requests within a transaction are executed
+sequentially.
+
+==== Close Behavior
+
+The default behavior of `close()` on a transaction is to commit. This can be changed:
+
+[source,java]
+----
+RemoteTransaction tx = cluster.transact("g");
+tx.onClose(Transaction.CLOSE_BEHAVIOR.ROLLBACK);
+tx.begin();
+// ... do work ...
+tx.close(); // rolls back instead of committing
+----
 
 [[gremlin-java-serialization]]
 === Serialization
@@ -1633,31 +1698,8 @@ re-construction machine-side.
 [[gremlin-javascript-transactions]]
 === Transactions
 
-To get a full understanding of this section, it would be good to start by reading the <<transactions,Transactions>>
-section of this documentation, which discusses transactions in the general context of TinkerPop itself. This section
-builds on that content by demonstrating the transactional syntax for Javascript.
-
-[source,javascript]
-----
-const g = traversal().with(new DriverRemoteConnection('ws://localhost:8182/gremlin'));
-const tx = g.tx(); // create a Transaction
-
-// spawn a new GraphTraversalSource binding all traversals established from it to tx
-const gtx = tx.begin();
-
-// execute traversals using gtx occur within the scope of the transaction held by tx. the
-// tx is closed after calls to commit or rollback and cannot be re-used. simply spawn a
-// new Transaction from g.tx() to create a new one as needed. the g context remains
-// accessible through all this as a sessionless connection.
-Promise.all([
-  gtx.addV("person").property("name", "jorge").iterate(),
-  gtx.addV("person").property("name", "josh").iterate()
-]).then(() => {
-  return tx.commit();
-}).catch(() => {
-  return tx.rollback();
-});
-----
+IMPORTANT: Transaction support over HTTP is not yet implemented in Gremlin-JavaScript. This will be addressed by the
+official 4.0.0 release.
 
 [[gremlin-javascript-lambda]]
 === The Lambda Solution
@@ -2157,8 +2199,8 @@ encoded in the Gremlin.Net GremlinLang and transmitted to the Gremlin traversal
 [[gremlin-dotnet-transactions]]
 === Transactions
 
-IMPORTANT: Transaction support over HTTP is not yet implemented in Gremlin.Net. This will be addressed in a future
-release.
+IMPORTANT: Transaction support over HTTP is not yet implemented in Gremlin.Net. This will be addressed by the official
+4.0.0 release.
 
 [[gremlin-dotnet-scripts]]
 === Submitting Scripts
@@ -2646,35 +2688,9 @@ re-construction machine-side.
 
 [[gremlin-python-transactions]]
 === Transactions
-IMPORTANT: 4.0.0-beta.1 Release - Transactions are currently disabled in this beta release.
-
-To get a full understanding of this section, it would be good to start by reading the <<transactions,Transactions>>
-section of this documentation, which discusses transactions in the general context of TinkerPop itself. This section
-builds on that content by demonstrating the transactional syntax for Python.
-
-[source,python]
-----
-g = traversal().with_remote(DriverRemoteConnection('ws://localhost:8182/gremlin'))
 
-# Create a Transaction.
-tx = g.tx()
-
-# Spawn a new GraphTraversalSource, binding all traversals established from it to tx.
-gtx = tx.begin()
-
-try:
-    # Execute a traversal within the transaction.
-    gtx.add_v("person").property("name", "Lyndon").iterate(),
-
-    # Commit the transaction. The transaction can no longer be used and cannot be re-used.
-    # A new transaction can be spawned through g.tx().
-    # The context of g remains sessionless throughout the process.
-    tx.commit()
-except Exception as e:
-    # Rollback the transaction if an error occurs.
-    tx.rollback()
-
-----
+IMPORTANT: Transaction support over HTTP is not yet implemented in Gremlin-Python. This will be addressed by the
+official 4.0.0 release.
 
 [[gremlin-python-gvalue]]
 === GValue Parameterization
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index ed1e81f14c..a081e209b3 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -56,7 +56,6 @@ traversal strategies may not function properly.
 
 [[transactions]]
 == Traversal Transactions
-IMPORTANT: 4.0.0-beta.1 Release - Transactions are currently disabled in this beta release.
 
 image:gremlin-coins.png[width=100,float=right] A link:http://en.wikipedia.org/wiki/Database_transaction[database transaction]
 represents a unit of work to execute against the database. A traversals unit of work is affected by usage convention
@@ -89,10 +88,10 @@ The above example is straightforward and represents a good starting point for di
 in relation to the usage convention and graph provider caveats alluded to earlier.
 
 Focusing on remote contexts first, note that it is still possible to issue traversals from `g`, but those will have a
-transaction scope outside of `gtx` and will simply `commit()` on the server if successfully executed or `rollback()`
-on the server otherwise (i.e. one traversal is one transaction). Each isolated transaction will require its own
-`Transaction` object. Multiple `begin()` calls on the same `Transaction` object will produce `GraphTraversalSource`
-instances that are bound to the same transaction, therefore:
+transaction scope outside of `gtx` and will simply behave as self-contained units of work where the graph's own
+transaction semantics apply (i.e. one traversal is one transaction). Each isolated transaction will require its own
+`Transaction` object. Multiple `begin()` calls on the same `Transaction` object are not permitted and will throw an
+`IllegalStateException`:
 
 [source,java]
 ----
@@ -100,17 +99,16 @@ GraphTraversalSource g = traversal().with(conn);
 Transaction tx1 = g.tx();
 Transaction tx2 = g.tx();
 
-// both gtx1a and gtx1b will be bound to the same transaction
-GraphTraversalSource gtx1a = tx1.begin();
-GraphTraversalSource gtx1b = tx1.begin();
-
-// g and gtx2 will not have knowledge of what happens in tx1
+// gtx1 and gtx2 are independent transactions
+GraphTraversalSource gtx1 = tx1.begin();
 GraphTraversalSource gtx2 = tx2.begin();
+
+// g operates outside of both tx1 and tx2
 ----
 
-In remote cases, `GraphTraversalSource` instances spawned from `begin()` are safe to use in multiple threads though
-on the server side they will be processed serially as they arrive. The default behavior of `close()` on a
-`Transaction` for remote cases is to `commit()`, so the following re-write of the earlier example is also valid:
+In remote cases, `GraphTraversalSource` instances spawned from `begin()` are safe to use from a single thread. The
+default behavior of `close()` on a `Transaction` for remote cases is to `commit()`, so the following re-write of the
+earlier example is also valid:
 
 [source,java]
 ----
@@ -137,12 +135,45 @@ graph's transaction model. In most cases, inspection of that object will indicat
 `AbstractThreadLocalTransaction` class, which means that the transaction is bound to the current thread and therefore
 all traversals that execute within that thread are tied to that transaction.
 
-A `ThreadLocal` transaction differs then from the remote case described before because technically any traversal
+A `ThreadLocal` transaction differs then from the remote case described before because technically any traversals
 spawned from `g` or from a `Transaction` will fall under the same transaction scope. As a result, it is wise, when
 trying to write context agnostic Gremlin, to follow the more rigid conventions of the initial example.
 
 The sub-sections that follow offer a bit more insight into each of the usage contexts.
 
+[[tx-remote]]
+=== Remote
+
+Remote transactions operate over the HTTP API. When `g.tx().begin()` is called, the driver sends a begin request to
+the server, which opens a transaction and returns a server-generated transaction ID. All subsequent traversals spawned
+from the resulting `GraphTraversalSource` automatically include this transaction ID in their requests. The server
+routes those requests to the same underlying graph transaction. Calling `tx.commit()` or `tx.rollback()` closes the
+transaction on the server.
+
+The HTTP protocol details are as follows:
+
+. The client sends `g.tx().begin()` with a `g` field identifying the target traversal source. No transaction ID is
+  included on this initial request.
+. The server opens a transaction, generates a transaction ID (a UUID string), and returns it in both the response body
+  (as a `transactionId` field in a map) and the `X-Transaction-Id` response header.
+. For all subsequent requests within the transaction, the client includes the transaction ID in both the
+  `X-Transaction-Id` request header and the `transactionId` field of the request body.
+. The client closes the transaction by sending `g.tx().commit()` or `g.tx().rollback()` with the transaction ID
+  attached.
+
+The graph alias specified in the begin request is locked for the lifetime of the transaction. If a subsequent request
+carries a different alias, the server rejects it with HTTP 400, preventing cross-graph operations within a single
+transaction.
+
+All requests within a transaction must reach the same server instance because transaction state is local to the server
+that created it. The TinkerPop Java GLV handles this automatically by pinning a transaction to a single host at
+creation time. In load-balanced deployments, the `X-Transaction-Id` header is available for load balancers to
+implement sticky routing without parsing the request body.
+
+If a traversal within an open transaction fails (bad syntax, runtime error, etc.), the server returns the error for
+that request but keeps the transaction open. The client can retry, submit other traversals, or explicitly roll back.
+Only an explicit commit, explicit rollback, or server-side timeout closes a transaction.
+
 [[tx-embedded]]
 === Embedded
 
@@ -269,26 +300,14 @@ the exact same behaviors and link:https://en.wikipedia.org/wiki/ACID[ACID] guara
 [[tx-gremlin-server]]
 === Gremlin Server
 
-The available capability for transactions with <<gremlin-server,Gremlin Server>> is dependent upon the method of
-interaction that is used. The preferred method for <<connecting-gremlin-server,interacting with Gremlin Server>>
-is via websockets and bytecode based requests. The start of the <<transactions,Transactions Section>> describes this
-approach in detail with examples.
-
-Gremlin Server also has the option to accept Gremlin-based scripts. The scripting approach provides access to the
-Graph API and thus also the transactional model described in the <<tx-embedded,embedded>> section. Therefore a single
-script can have the ability to execute multiple transactions per request with complete control provided to the
-developer to commit or rollback transactions as needed.
-
-IMPORTANT: 4.0.0-beta.1 Release - Transactions are currently disabled in this beta release.
+The available capability for transactions with <<gremlin-server,Gremlin Server>> is dependent upon the graph
+configured on the server. The graph must support transactions for `g.tx().begin()` to succeed. If the graph does not
+support transactions (e.g. a basic `TinkerGraph`), the server returns an error. Use `TinkerTransactionGraph` or
+another transaction-capable graph implementation.
 
-There are two methods for sending scripts to Gremlin Server: sessionless and session-based. With sessionless requests
-there will always be an attempt to close the transaction at the end of the request with a commit if there are no errors
-or a rollback if there is a failure. It is therefore unnecessary to close transactions manually within scripts
-themselves. By default, session-based requests do not have this quality. The transaction will be held open on the
-server until the user closes it manually. There is an option to have automatic transaction management for sessions.
-More information on this topic can be found in the <<considering-transactions,Considering Transactions>> Section.
+The Gremlin Server implements the transactions as part of the HTTP API and it no longer runs on top of sessions.
 
-IMPORTANT: 4.0.0-beta.1 Release - Sessions have been removed. All scripts are now sessionless.
+IMPORTANT: Sessions have been removed in 4.0.0. Transactions are no longer tied to sessions.
 
 [[tx-rgp]]
 === Remote Gremlin Providers