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

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

commit bd598c2c041fa5442de3666f7076dba9fc6812c1
Author: Ken Hu <[email protected]>
AuthorDate: Fri Jan 23 11:08:50 2026 -0800

    Some diagrams for potential tx design
---
 docs/src/dev/transactions/http-api-spec.md         | 145 +++++++++++++++++++++
 .../dev/transactions/remote-transaction-flow.md    | 100 ++++++++++++++
 pom.xml                                            |  12 +-
 3 files changed, 246 insertions(+), 11 deletions(-)

diff --git a/docs/src/dev/transactions/http-api-spec.md 
b/docs/src/dev/transactions/http-api-spec.md
new file mode 100644
index 0000000000..31bcffcf83
--- /dev/null
+++ b/docs/src/dev/transactions/http-api-spec.md
@@ -0,0 +1,145 @@
+# HTTP Transaction API Specification
+
+## Overview
+
+The Gremlin Server exposes a REST API for transaction management. Transactions 
are modeled as resources with unique IDs, and all operations within a 
transaction include the transaction ID in the URL path.
+
+**NOTE** This is very preliminary and can easily be modeled by a single 
endpoint.
+
+## API Endpoints
+
+### Non-Transactional Traversal
+```
+POST /gremlin
+```
+Standard Gremlin Server endpoint for executing traversals without a 
transaction.
+
+### Begin Transaction
+```
+POST /gremlin/tx
+
+Response: 201 Created
+Location: /gremlin/tx/{txId}
+{
+  "txId": "550e8400-e29b-41d4-a716-446655440000"
+}
+```
+Creates a new transaction and returns a unique transaction ID.
+
+### Execute Traversal Within Transaction
+```
+POST /gremlin/tx/{txId}
+
+Response: 200 OK
+(Standard Gremlin response)
+```
+Executes a traversal within the context of the specified transaction. Request 
body is the same as `POST /gremlin`, but the traversal is scoped to the 
transaction.
+
+### Get Transaction Status
+```
+GET /gremlin/tx/{txId}
+
+Response: 200 OK
+{
+  "txId": "550e8400-e29b-41d4-a716-446655440000",
+  "status": "ACTIVE"
+}
+```
+Returns the current status of a transaction (ACTIVE, COMMITTED, or 
ROLLED_BACK).
+
+### Commit Transaction
+```
+POST /gremlin/tx/{txId}/commit
+
+Response: 200 OK
+{
+  "txId": "550e8400-e29b-41d4-a716-446655440000",
+  "status": "COMMITTED"
+}
+```
+Commits all changes made within the transaction.
+
+### Rollback Transaction
+```
+POST /gremlin/tx/{txId}/rollback
+
+Response: 200 OK
+{
+  "txId": "550e8400-e29b-41d4-a716-446655440000",
+  "status": "ROLLED_BACK"
+}
+```
+Rolls back all changes made within the transaction.
+
+### Abort Transaction
+```
+DELETE /gremlin/tx/{txId}
+
+Response: 200 OK
+{
+  "txId": "550e8400-e29b-41d4-a716-446655440000",
+  "status": "ROLLED_BACK"
+}
+```
+Alternative to rollback - aborts the transaction and rolls back all changes.
+
+## Error Responses
+
+### Transaction Not Found
+```
+GET /gremlin/tx/invalid-id
+
+Response: 404 Not Found
+{
+  "error": "Transaction not found",
+  "txId": "invalid-id"
+}
+```
+
+### Transaction Already in Terminal State
+```
+POST /gremlin/tx/{txId}/commit
+
+Response: 409 Conflict
+{
+  "error": "Transaction already in terminal state",
+  "txId": "550e8400-e29b-41d4-a716-446655440000",
+  "status": "COMMITTED"
+}
+```
+
+### Transaction Execution Error
+```
+POST /gremlin/tx/{txId}
+
+Response: 500 Internal Server Error
+{
+  "error": "Traversal execution failed",
+  "message": "...",
+  "txId": "550e8400-e29b-41d4-a716-446655440000"
+}
+```
+
+## Transaction ID Format
+
+- **Format**: UUID
+- **Example**: `550e8400-e29b-41d4-a716-446655440000`
+- **Generation**: Server-generated on `POST /gremlin/tx`
+- **Usage**: Included in all subsequent requests as URL path parameter
+- **Purpose**: Routes requests to correct transaction context on server
+
+## Endpoint Summary Diagram
+
+```mermaid
+flowchart TD
+    A[Client] -->|POST /gremlin| B[Non-Transactional Execution]
+    A -->|POST /gremlin/tx| C[Begin Transaction]
+    C -->|Returns txId| D[Transaction Active]
+    D -->|POST /gremlin/tx/{txId}| E[Execute in Transaction]
+    D -->|GET /gremlin/tx/{txId}| F[Get Status]
+    D -->|POST /gremlin/tx/{txId}/commit| G[Commit]
+    D -->|POST /gremlin/tx/{txId}/rollback| H[Rollback]
+    D -->|DELETE /gremlin/tx/{txId}| H
+    G --> I[Transaction Committed]
+    H --> J[Transaction Rolled Back]
+```
diff --git a/docs/src/dev/transactions/remote-transaction-flow.md 
b/docs/src/dev/transactions/remote-transaction-flow.md
new file mode 100644
index 0000000000..a72a1dee49
--- /dev/null
+++ b/docs/src/dev/transactions/remote-transaction-flow.md
@@ -0,0 +1,100 @@
+# Remote Transaction Flow
+
+## Overview
+
+This diagram shows the complete client-server interaction for remote 
transactions over HTTP. Transactions are thread-bound: when `tx.begin()` is 
called, all subsequent traversals on that thread automatically participate in 
the transaction.
+
+Making these remote transactions thread-bound on the GLV-side makes it match 
the behavior for embedded transactions which are threaded by default. The API 
will likely force transactions to disallow multithreaded transactions which 
matches traditional relation database behavior. However, a subsequent update 
will likely allow multiple of these thread-bound transactions to exist, that 
is, a single thread will be able to have one or more transactions.
+
+## Sequence Diagram
+
+```mermaid
+sequenceDiagram
+    participant Client as Client (Thread 1)
+    participant GTS as GraphTraversalSource
+    participant Conn as DriverRemoteConnection
+    participant Server as Gremlin Server
+
+    Note over Client,Server: Setup
+    Client->>Conn: traversal().with(connection)
+    Conn-->>Client: GraphTraversalSource (g)
+
+    Note over Client,Server: Begin Transaction
+    Client->>GTS: g.tx()
+    GTS-->>Client: Transaction (tx)
+    Client->>Conn: tx.begin()
+    Conn->>Server: POST /gremlin/tx
+    Server-->>Conn: 201 Created<br/>{txId: "abc-123"}
+    Note over Conn: Store txId in ThreadLocal
+    Conn-->>Client: void
+
+    Note over Client,Server: Execute Traversals (Thread-Bound)
+    Client->>GTS: g.addV("person")
+    GTS->>Conn: submit(traversal)
+    Note over Conn: Check ThreadLocal: txId = "abc-123"
+    Conn->>Server: POST /gremlin/tx/abc-123
+    Server-->>Conn: 200 OK
+    Conn-->>GTS: Result
+    GTS-->>Client: Traversal
+
+    Client->>GTS: g.V().has("name", "x")
+    GTS->>Conn: submit(traversal)
+    Note over Conn: Check ThreadLocal: txId = "abc-123"
+    Conn->>Server: POST /gremlin/tx/abc-123
+    Server-->>Conn: 200 OK
+    Conn-->>GTS: Result
+    GTS-->>Client: Traversal
+
+    Note over Client,Server: Commit Transaction
+    Client->>Conn: tx.commit()
+    Conn->>Server: POST /gremlin/tx/abc-123/commit
+    Server-->>Conn: 200 OK<br/>{status: "COMMITTED"}
+    Note over Conn: Clear ThreadLocal
+    Conn-->>Client: void
+```
+
+## Rollback Flow
+
+```mermaid
+sequenceDiagram
+    participant Client
+    participant Conn as DriverRemoteConnection
+    participant Server as Gremlin Server
+
+    Note over Client,Server: Transaction is Active
+    Client->>Conn: tx.rollback()
+    Conn->>Server: POST /gremlin/tx/abc-123/rollback
+    Server-->>Conn: 200 OK<br/>{status: "ROLLED_BACK"}
+    Note over Conn: Clear ThreadLocal
+    Conn-->>Client: void
+```
+
+## Thread-Bound Behavior
+
+### Key Points
+
+1. **ThreadLocal Storage**: When `tx.begin()` is called, the transaction ID is 
stored in a ThreadLocal variable
+2. **Automatic Binding**: All traversals submitted on that thread 
automatically check ThreadLocal for an active transaction
+3. **Endpoint Selection**: 
+   - If transaction ID found in ThreadLocal → use `POST /gremlin/tx/{txId}`
+   - If no transaction ID → use `POST /gremlin` (non-transactional)
+4. **Thread Cleanup**: `tx.commit()` or `tx.rollback()` clears the ThreadLocal 
for that thread
+5. **Thread Isolation**: Different threads can have different active 
transactions
+
+### Behavior Diagram
+
+```mermaid
+flowchart TD
+    A[Client calls tx.begin] --> B[POST /gremlin/tx]
+    B --> C[Server returns txId]
+    C --> D[Store txId in ThreadLocal]
+    D --> E[Client executes g.addV...]
+    E --> F{Check ThreadLocal}
+    F -->|txId found| G[POST /gremlin/tx/txId]
+    F -->|No txId| H[POST /gremlin]
+    G --> I[Execute in transaction]
+    H --> J[Execute non-transactional]
+    I --> K[Client calls tx.commit]
+    K --> L[POST /gremlin/tx/txId/commit]
+    L --> M[Clear ThreadLocal]
+```
diff --git a/pom.xml b/pom.xml
index 8ea5fcd9ca..4ca108bb17 100644
--- a/pom.xml
+++ b/pom.xml
@@ -127,23 +127,13 @@ limitations under the License.
         <module>gremlin-core</module>
         <module>gremlin-annotations</module>
         <module>gremlin-test</module>
-        <module>gremlin-util</module>
         <module>gremlin-groovy</module>
         <module>tinkergraph-gremlin</module>
-        <module>gremlin-javascript</module>
-        <module>gremlin-python</module>
-        <module>gremlin-dotnet</module>
-        <module>gremlin-go</module>
-        <module>hadoop-gremlin</module>
-        <module>spark-gremlin</module>
-        <module>neo4j-gremlin</module>
-        <module>sparql-gremlin</module>
         <module>gremlin-driver</module>
         <module>gremlin-console</module>
         <module>gremlin-server</module>
         <module>gremlin-tools</module>
-        <module>gremlint</module>
-        <module>gremlin-mcp</module>
+        <module>gremlin-util</module>
     </modules>
     <scm>
         <connection>scm:git:[email protected]:apache/tinkerpop.git</connection>

Reply via email to