[ 
https://issues.apache.org/jira/browse/TINKERPOP-3253?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18089947#comment-18089947
 ] 

ASF GitHub Bot commented on TINKERPOP-3253:
-------------------------------------------

spmallette commented on code in PR #3464:
URL: https://github.com/apache/tinkerpop/pull/3464#discussion_r3436975492


##########
docs/src/reference/the-traversal.asciidoc:
##########
@@ -60,8 +60,57 @@ traversal strategies may not function properly.
 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
 (i.e. the method of <<connecting-gremlin, connecting>>) and the graph 
provider's transaction model. Without diving
-deeply into different conventions and models the most general and recommended 
approach to working with transactions is
-demonstrated as follows:
+deeply into different conventions and models, the recommended way to work with 
transactions is to wrap the unit of
+work in a closure passed to `executeInTx` (or `evaluateInTx` when a value must 
be returned), which manages the
+transaction lifecycle for you:
+
+[source,java]
+----
+GraphTraversalSource g = traversal().with(graph);
+// or
+GraphTraversalSource g = traversal().with(conn);
+
+// the closure receives the transaction-bound gtx; the transaction is begun
+// automatically, committed when the closure completes normally, and rolled
+// back if it throws
+g.executeInTx(gtx -> {
+    gtx.addV('person').iterate();
+    gtx.addV('software').iterate();
+});
+
+// use evaluateInTx when the unit of work needs to return a value
+long count = g.evaluateInTx(gtx -> gtx.V().count().next());
+----
+
+This closure form is preferred for several reasons:
+
+* *Correctness by default.* The transaction is always committed on success and 
rolled back on any error (or other
+abnormal exit), so partial work is never left dangling and there is no way to 
forget a `commit()` or a `rollback()` in
+an error path.
+* *Less boilerplate.* The common begin/do-work/commit cycle becomes a single 
call, removing the repetitive
+try/catch lifecycle management that is easy to get subtly wrong.
+* *Steers you toward the transaction-bound source.* The closure receives `gtx` 
as its argument, so the transactional
+source is the one already in hand for the unit of work. This makes it natural 
to run traversals against `gtx` rather
+than accidentally against the non-transactional `g` (which would execute as a 
separate implicit transaction).
+* *It papers over the remote/embedded paradigm difference (Java).* In Java a 
`GraphTraversalSource` can be backed by
+either a remote connection or an embedded graph, and the two model 
transactions differently. In the *remote* case
+`g.tx()` returns a distinct transaction object each time, keyed by a 
server-side transaction ID, and the `gtx` spawned
+from it is a genuinely separate `GraphTraversalSource` from `g` — issuing a 
traversal against `g` instead of `gtx`
+silently runs as its own implicit transaction. In the *embedded* case `g.tx()` 
returns a thread-bound transaction (the
+traditional Java model in which the transaction is associated with the current 
thread), so `g` and `gtx` actually
+share the same transaction scope. Because the closure hands you the correct 
transaction-bound `gtx` and owns the
+lifecycle, the exact same code is correct under both paradigms; you do not 
have to reason about whether `g` and `gtx`
+refer to the same underlying transaction. (The non-Java GLVs are always 
remote, so this distinction does not arise
+there.)
+
+The closure runs the unit of work exactly once (there is no automatic retry). 
If the closure throws, the original
+error is re-raised after the rollback; if the `commit()` itself fails, the 
commit error is raised and a rollback is
+still attempted to release server-side resources.
+
+Manual transaction control (calling `begin()`, `commit()`, and `rollback()` 
yourself, shown below) remains fully

Review Comment:
   "fit the use case — for example, when the" - just make it two sentences.





> Add convenience lambdas for transactions
> ----------------------------------------
>
>                 Key: TINKERPOP-3253
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-3253
>             Project: TinkerPop
>          Issue Type: Improvement
>          Components: dotnet, driver, go, javascript, python
>    Affects Versions: 4.0.0
>            Reporter: Ken Hu
>            Priority: Major
>
> A common usage for transactions is just to begin, do one operation and then 
> commit. This currently requires three separate calls. Add some convenience 
> methods that will wrap the operation in a begin() and commit().
> Originally discussed in: 
> https://lists.apache.org/thread/khnz10j0ox640ch2ooq3zkpy4kmo6wxj



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to