2

I need some help understanding transactions for gremlin-server and janusgraph. Checking the capabilities of a Graph instance via features for gremlin-server:

gremlin> :remote connect tinkerpop.server conf/gremlin-server.yaml
==>Configured host.docker.internal/192.168.65.2:8182
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [host.docker.internal/192.168.65.2:8182] - type ':remote console' to return to local mode
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.features()
==>FEATURES
> GraphFeatures
>-- Transactions: false
>-- Computer: true
>-- Persistence: true
>-- ConcurrentAccess: false
>-- ThreadedTransactions: false
>-- IoRead: true
>-- IoWrite: true
>-- OrderabilitySemantics: true
>-- ServiceCall: true
...

Checking the capabilities of a Graph instance via features for janusgraph:

gremlin> :remote connect tinkerpop.server conf/janusgraph.yaml
==>Configured host.docker.internal/192.168.65.2:8183
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [host.docker.internal/192.168.65.2:8183] - type ':remote console' to return to local mode
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.features()
==>FEATURES
> GraphFeatures
>-- Computer: true
>-- ConcurrentAccess: true
>-- ThreadedTransactions: true
>-- IoRead: true
>-- IoWrite: true
>-- Transactions: true
>-- Persistence: true
...

Gremlin-server does not support transactions, whereby janusgraph does. Now, does this only hold for the specific graph instance we created? Or, the other way around, does not gremlin-server support transactions at all? If gremlin-server supports transactions, how to configure transactions for graphs in gremlin-server.

Apart from that, Tinkerpop documentation about gremlin-server transactions states:

The third and final point involves transactions. Under this model, one traversal is equivalent to a single transaction and there is no way in TinkerPop to string together multiple traversals into the same transaction.

Can someone rephrase this paragraph, preferably with some example. Thinking out loud, my first approach to explain would be the following:

g.addV("test") // one traversal and a single transaction
g.addV("test").addV("test") // not a single transaction

Maybe this also explains why g.addV("test").addV("test").next() only returns last vertex created, another ....next() returns E0903: there are no results left. At first, I assumed first next() call would return first vertex created and second next() call would return second vertex created. How to get each vertex when calling g.addV("test").addV("test")?

Hope it is not to confusing. Maybe I am mixing things up here.

EDIT:

tx := gremlingo.Traversal_().WithRemote(...).Tx()
gtx, err := tx.Begin()
if err != nil {
    tx.Close()
    return nil, err
}

// Just some query ...
_, err = gtx.AddV("test").Next()
if err != nil {
    tx.Rollback()
    return nil, err
}

err = tx.Commit()
if err != nil {
    tx.Rollback()
    return nil, err
}

Above code block works fine when connecting to janusgraph, but fails with stackTrace:java.lang.UnsupportedOperationException: Graph does not support transactions when connecting to gremlin-server. Does not gremlin-server support transactions at all or just the graph instance used? If gremlin-server supports transactions, how to configure graph instance to allow transactions.

norym
  • 602
  • 2
  • 8
  • 18
  • 1
    Maybe a real answer later. Gremlin Server, when used without a session, applies a single transaction to each remote traversal. The traversal ending steps like next() only show the content of the latest traversal step. If your want more use g.addV("test").store("v").addV("test").store("v").cap("v"). The start of your question sounds as a JanusGraph issue, which version do you use? – HadoopMarc Dec 14 '22 at 07:06
  • Greatly appreciated. I am using gremlin-go driver (https://github.com/apache/tinkerpop/tree/master/gremlin-go v3.6.1), tinkerpop/gremlin-server:3.6 and docker.io/janusgraph/janusgraph:0.6.2. Did not know about .store() and .cap(), do you have some references. How to handle sessions in gremlin/gremlin-go driver. Do you have some good examples or gremlin-go snippets? Any thoughts about https://tinkerpop.apache.org/docs/current/reference/#transactions? – norym Dec 14 '22 at 13:06
  • You can use session with Go by specifying a session ID, see: https://tinkerpop.apache.org/docs/current/reference/#gremlin-go-configuration Do not forget to g.tx().commit() any changes in that case. cap() is in the TinkerPop ref docs. Instead of store() - old name - I should have used aggregate(). – HadoopMarc Dec 14 '22 at 14:25
  • I am still a bit confused. According to the gremlingo code and documentation, I am unable to specify a session via `NewDriverRemoteConnection` settings but `g.Tx().Begin()` creates a new session and handles session management. When creating a session manually via `"DriverRemoteConnection".CreateSession`, I am not able to commit the session. Apart from that, using `g.Tx().Begin()` with janusgraph works fine, with gremling-server I get the following `stackTrace:java.lang.UnsupportedOperationException: Graph does not support transactions`. – norym Dec 16 '22 at 09:54
  • Now I am back at my first question: Does gremlin-server support transactions (via sessions) at all? If yes, does it need to be configured on graph-level or db-level? If yes, where to configure/enable transactions (via sessions) (on graph-level or db-level) for gremlin-server? – norym Dec 16 '22 at 09:57
  • I was not aware of the TinkerPop feature to manage transactions from the client through a remote connection (so your citation about transactions from the TinkerPop ref docs seems similarly outdated). Using this new transaction feature is preferable over using a session, which keeps state at the script level, rather than the transaction level. Regarding the remote connection to JanusGraph, please see the part of my answer about using the traversal() object. There are still things I do not understand in the details you provide. – HadoopMarc Dec 17 '22 at 16:13

1 Answers1

3

Gremlin Server does not have graph features. It hosts pre-configured graphs of any type that are remotely accessible to clients. If you want JanusGraph to open graphs dynamically with a command from the client, please check the following part of the JanusGraph ref docs:

https://docs.janusgraph.org/operations/dynamic-graphs/

In your second code block you never really assigned a TinkerGraph to the graph variable in the Gremlin Console. You can check by issuing:

gremlin> :remote connect tinkerpop.server conf/remote.yaml
gremlin> :remote console
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.getClass()
==>class org.janusgraph.graphdb.database.StandardJanusGraph
gremlin> graph123 = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph123.features()
No such property: graph123 for class: Script10
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> TinkerGraph.open().features()
==>FEATURES
> GraphFeatures
>-- Computer: true
>-- ConcurrentAccess: false
>-- ThreadedTransactions: false
>-- IoRead: true
>-- IoWrite: true
>-- Transactions: false
>-- Persistence: true

Btw, the idiomatic way to create a remote connection with TinkerPop-compliant graph is to use the traversal() object:

g = traversal().withRemote(DriverRemoteConnection.using("localhost",8182,"g"))

This was introduced to accomodate the cloud graph providers but also prevents confusing situations like yours.

Added after the question was edited:

The JanusGraph distribution includes 2 scrips to start JanusGraph server: bin/janusgraph.sh and bin/janusgraph-server.sh. The first script starts a Gremlin Server instance, a Cassandra instance and an Elasticsearch instance. The graph served in this configuration supports transactions. The second script only starts Gremlin Server using the provided yaml configuration file or the default conf/gremlin-server/gremlin-server.yaml file. In the default configuration the storage inmemory backend is applied. This backend does not support transactions.

HadoopMarc
  • 1,356
  • 3
  • 11
  • You are right, I messed things up in my code blocks. I corrected it. As you explained, I create a remote connection via `gremlingo.Traversal_().WithRemote(gremlingo.NewDriverRemoteConnection(source))`. And you are also correct by the fact that I might mix up things. Your help is greatly appreciated. One thing I have not figured out yet is explained in an edit of the original question. – norym Dec 19 '22 at 15:14
  • Sorry @HadoopMarc, did not notice your edit on the answer. Regarding your last paragraph: When using gremlin-server only, am I able to configure gremlin-server to support transactions. If so, how to adapt the configuration to support transactions. Or, how to host a graph via gremlin-server that supports transactions? Apart from that where to read about the storage in-memory backend? – norym Jan 02 '23 at 10:29