Enable autocommit in GremlinServer#3423
Conversation
This behaves the same as the TraversalOpProcessor would have in the 3.x line. All traversals are now transactional if the underlying Graph supports transactions. Traversals that aren't explicitly in a transaction are now wrapped into their own implicit transaction and the server will autocommit on sucess and rollback on failure. Assisted-by: Kiro:claude-opus-4-6
| * On error: roll back the transaction so that partial mutations are not persisted. | ||
|
|
||
| This auto-commit behavior ensures that users who do not use explicit transactions still get durable writes on success | ||
| and clean rollback on failure. Graph system providers implementing their own server or HTTP endpoint must replicate |
There was a problem hiding this comment.
Since we are using "must", is there a consequence if they don't (Exception)? Can we document that?
| .get(GraphSONTokens.VALUEPROP).get(0) | ||
| .get(GraphSONTokens.VALUEPROP).intValue()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Is there also a way to test stale open transactions?
| final Object result = scriptEngine.eval(message.getGremlin(), mergedBindings); | ||
|
|
||
| final String bulkingSetting = context.getChannelHandlerContext().channel().attr(StateKey.REQUEST_HEADERS).get().get(Tokens.BULK_RESULTS); | ||
| // bulking only applies if it's gremlin-lang, and per request token setting takes precedence over header setting. | ||
| // The serializer check is temporarily needed because GraphSON hasn't been removed yet and doesn't support bulking. | ||
| final boolean bulking = language.equals("gremlin-lang") && serializer instanceof GraphBinaryMessageSerializerV4 ? | ||
| (args.containsKey(Tokens.BULK_RESULTS) ? | ||
| Objects.equals(args.get(Tokens.BULK_RESULTS), "true") : | ||
| Objects.equals(bulkingSetting, "true")) : | ||
| false; |
There was a problem hiding this comment.
Could any of these lines throw an error and should be in the rollback try catch in this case?
|
VOTE +1 |
| own transaction semantics apply. Each traversal executes within its own transaction as managed by the graph | ||
| implementation itself. Transactional requests participate in a transaction opened via `g.tx().begin()`, where the | ||
| client explicitly controls the lifecycle through `g.tx().commit()` and `g.tx().rollback()`. | ||
| Non-transactional requests (those without a `transactionId`) behave as self-contained units of work. If the underlying |
There was a problem hiding this comment.
In the provider docs we wrote about "graphs that don't support transactions" and here we talk about "non-transactional". I wonder if we should avoid that language and just better introduce the notion of implicit and explicit transactions and talk only in those terms. In this way, all graphs have a transaction and they all support implicit (i.e. auto-commit, sessionless, non-transactional, etc. in the old parlance) and may support explicit (i.e. manual commit, session, transactional, etc. in the old parlance). In this way we don't drag back any of the older terminology.
This behaves the same as the TraversalOpProcessor would have in the 3.x line. All traversals are now transactional if the underlying Graph supports transactions. Traversals that aren't explicitly in a transaction are now wrapped into their own implicit transaction and the server will autocommit on sucess and rollback on failure.
Assisted-by: Kiro:claude-opus-4-6