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


The following commit(s) were added to refs/heads/tx-diag by this push:
     new 604b753020 update to latest design
604b753020 is described below

commit 604b75302014a60b579c4be81c926ae46d0f6396
Author: Ken Hu <[email protected]>
AuthorDate: Thu Feb 5 11:17:47 2026 -0800

    update to latest design
---
 docs/src/dev/transactions/http-api-spec.md | 200 ++++++++++++++---------------
 1 file changed, 98 insertions(+), 102 deletions(-)

diff --git a/docs/src/dev/transactions/http-api-spec.md 
b/docs/src/dev/transactions/http-api-spec.md
index 4e54262f2a..0e3016278b 100644
--- a/docs/src/dev/transactions/http-api-spec.md
+++ b/docs/src/dev/transactions/http-api-spec.md
@@ -1,129 +1,125 @@
-# HTTP Transaction API Specification
+## Request Format Specification
 
-## Overview
+**Endpoint:** `POST /gremlin`  
+**Content-Type:** `application/json`
 
-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.
+### Required Fields
 
-**NOTE** This is very preliminary and can easily be modeled by a single 
endpoint.
+| Field | Type | Description |
+|-------|------|-------------|
+| `gremlin` | String | The Gremlin query to execute. For tx control: 
`"g.tx().begin()"`, `"g.tx().commit()"`, `"g.tx().rollback()"` |
+| `g` | String | Graph/traversal source alias (e.g., `"g"`, `"gmodern"`, 
`"gcrew"`) |
+| `transactionId` | String | Client-generated UUID. Must be consistent across 
all requests in the same transaction |
 
-## API Endpoints
+### Required Header
 
-### Non-Transactional Traversal
-```
-POST /gremlin
-```
-Standard Gremlin Server endpoint for executing traversals without a 
transaction.
+| Header | Type | Description |
+|--------|------|-------------|
+| `X-Transaction-Id` | String | Same value as body `transactionId`. Used for 
load balancer routing |
 
-### 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.
+## Transaction Control Commands
 
-### Execute Traversal Within Transaction
-```
-POST /gremlin/tx/{txId}
+The server must detect these exact Gremlin strings to handle transaction 
lifecycle:
 
-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.
+```mermaid
+flowchart LR
+    subgraph detection["Transaction Control Detection"]
+        begin['"g.tx().begin()"']
+        commit['"g.tx().commit()"']
+        rollback['"g.tx().rollback()"']
+        other["Any other gremlin"]
+    end
 
-### Get Transaction Status
+    begin --> beginAction["Create new TransactionContext<br/>• Allocate 
dedicated thread<br/>• Open graph transaction<br/>• Start inactivity 
timeout<br/>• Store context keyed by transactionId"]
+    
+    commit --> commitAction["Commit and cleanup<br/>• Commit graph 
transaction<br/>• Remove TransactionContext<br/>• Release dedicated 
thread<br/>• Cancel timeout timer"]
+    
+    rollback --> rollbackAction["Rollback and cleanup<br/>• Rollback graph 
transaction<br/>• Remove TransactionContext<br/>• Release dedicated 
thread<br/>• Cancel timeout timer"]
+    
+    other --> otherAction["Execute within transaction<br/>• Lookup 
TransactionContext by transactionId<br/>• Execute on transaction's thread<br/>• 
Reset inactivity timeout"]
 ```
-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).
+**IMPORTANT:** String matching should be exact (after trimming whitespace)
 
-### 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
+## Protocol Flow
 
-Response: 200 OK
-{
-  "txId": "550e8400-e29b-41d4-a716-446655440000",
-  "status": "ROLLED_BACK"
-}
-```
-Rolls back all changes made within the transaction.
+```mermaid
+sequenceDiagram
+    participant Client
+    participant Server
 
-### Abort Transaction
-```
-DELETE /gremlin/tx/{txId}
+    Note over Client,Server: 1. BEGIN TRANSACTION
 
-Response: 200 OK
-{
-  "txId": "550e8400-e29b-41d4-a716-446655440000",
-  "status": "ROLLED_BACK"
-}
-```
-Alternative to rollback - aborts the transaction and rolls back all changes.
+    Client->>Server: POST /gremlin<br/>Header: X-Transaction-Id: 
abc-123-def-456<br/>Body: {"gremlin": "g.tx().begin()", "g": "gmodern", 
"transactionId": "abc-123-def-456"}
+    
+    Note right of Server: Create TransactionContext<br/>• Allocate thread for 
tx<br/>• Open graph transaction<br/>• Start timeout timer
+    
+    Server-->>Client: 200 OK
 
-## Error Responses
+    Note over Client,Server: 2. EXECUTE OPERATIONS (repeat as needed)
 
-### Transaction Not Found
-```
-GET /gremlin/tx/invalid-id
+    Client->>Server: POST /gremlin<br/>Header: X-Transaction-Id: 
abc-123-def-456<br/>Body: {"gremlin": 
"g.addV('person').property('name','josh')", "g": "gmodern", "transactionId": 
"abc-123-def-456"}
+    
+    Note right of Server: Lookup TransactionContext<br/>Execute on tx 
thread<br/>Reset timeout timer
+    
+    Server-->>Client: 200 OK + results
 
-Response: 404 Not Found
-{
-  "error": "Transaction not found",
-  "txId": "invalid-id"
-}
-```
+    Note over Client,Server: 3. COMMIT or ROLLBACK
 
-### 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"
-}
+    Client->>Server: POST /gremlin<br/>Header: X-Transaction-Id: 
abc-123-def-456<br/>Body: {"gremlin": "g.tx().commit()", "g": "gmodern", 
"transactionId": "abc-123-def-456"}
+    
+    Note right of Server: Commit graph transaction<br/>Cleanup 
TransactionContext<br/>Release thread
+    
+    Server-->>Client: 200 OK
 ```
 
-### 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: Dual Transmission Design
+
+### Why Transaction ID Appears Twice
+
+```mermaid
+flowchart TB
+    subgraph request["HTTP Request Structure"]
+        subgraph headers["HTTP HEADERS"]
+            h1["Content-Type: application/json"]
+            h2["X-Transaction-Id: abc-123-def-456"]
+        end
+        subgraph body["HTTP BODY (JSON)"]
+            b1['"gremlin": "g.addV(\'person\')"']
+            b2['"g": "gmodern"']
+            b3['"transactionId": "abc-123-def-456"']
+        end
+    end
+
+    h2 -->|FOR LOAD BALANCER ROUTING| lb["Load Balancers, Proxies, API 
Gateways"]
+    b3 -->|FOR SERVER PROCESSING| server["Graph Database Server"]
 ```
 
-## Transaction ID Format
+### Architectural Rationale
+
+| Aspect | X-Transaction-Id HEADER | transactionId BODY FIELD |
+|--------|------------------------|--------------------------|
+| **Purpose** | Infrastructure routing | Application logic |
+| **Used by** | Load balancers, proxies, API gateways | Graph database server 
to lookup transaction state |
+| **Why needed** | Load balancers typically only inspect headers, not body. 
Enables sticky sessions without application-layer parsing. Works with any LB 
that supports header-based routing. | Server needs to associate request with 
correct transaction. Part of the Gremlin request protocol specification. 
Consistent with other request fields (gremlin, g, bindings). |
+
+### Load Balancer Sticky Routing
 
-- **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
+```mermaid
+flowchart TB
+    LB["Load Balancer<br/>(reads X-Transaction-Id header)"]
+    
+    LB --> ServerA["Server A<br/>tx: abc, def"]
+    LB --> ServerB["Server B<br/>tx: xyz, uvw"]
+    LB --> ServerC["Server C<br/>tx: 123, 456"]
+    
+    req1["Request with<br/>X-Transaction-Id: abc"] -.->|Always routes to| 
ServerA
+    req2["Request with<br/>X-Transaction-Id: xyz"] -.->|Always routes to| 
ServerB
+```
\ No newline at end of file

Reply via email to