We haven't touched "transactions" since TP3 was originally designed. They
have remained a feature for embedded use cases even in the face of the rise
of remote graph use cases and result in major inconsistencies that really
bother users.
As we close on 3.5.0, I figured that perhaps there was a chance to do
something radical about transactions. Basically, I'd like transactions to
work irrespective of remote or embedded usage and for them to have the same
API when doing so. In mulling it over for the last day or so I had a
realization that makes me believe that the following is possible:
g = traversal().withEmbedded(graph)
// or
g = traversal().withRemote(conn)
gtx = g.tx().create()
gtx.addV('person').iterate()
gtx.addV('software').iterate()
gtx.close() // alternatively you could explicitly commit() or rollback()
// you could still use g for sessionless, but gtx is "done" after
// you close so you will need to create() a new gtx instance for a
// fresh transaction
assert 2 == g.V().count().next()
Note that the create() method on tx() is the new bit of necessary syntax.
Technically, it is a do-nothing for embedded mode (and you could skip it
for thread-local auto-transactions) but all the documentation can be
shifted so that the API is identical to remote. The change would be
non-breaking as the embedded transaction approach would remain as it is,
but would no longer be documented as the preferred approach. Perhaps we
could one day disallow it but it's a bit of a tangle of ThreadLocal that
I'm not sure we want to touch in TP3.
What happens behind the scenes of g.tx().create() is that in remote cases
the RemoteConnection constructs a remote Transaction implementation which
basically is used to spawn new traversal source instances with a session
based connections. The remote Transaction object can't support transaction
listeners or special read-write/close configurations, but I don't think
that's a problem as those things don't make a lot of sense in remote use
cases.
>From the server perspective, this change would also mean that sessions
would have to accept bytecode and not just scripts, which technically
shouldn't be a problem.
One downside at the moment is that i'm thinking mostly in Java at the
moment. I'm not sure how this all works in other variants just yet, but I'd
hope to keep similar syntax.
I will keep experimenting tomorrow. If you have any thoughts on the matter,
I'd be happy to hear them. Thanks!