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 <[email protected]>
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

Reply via email to