Reputation: 11
I might be misunderstanding how transactions work in Gremlin. Here’s what I’m trying to test on a local TinkerPop Gremlin setup:
However, I keep encountering this error:
code:244 message:Conflict: element modified in another transaction attributes
Shouldn't the read happen on snapshot data?
This is my code:
package main
import (
"fmt"
"log"
"sync"
"time"
gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver"
)
func main() {
// Initialize Gremlin client
client, err := gremlingo.NewDriverRemoteConnection("ws://localhost:8182/gremlin")
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
g := gremlingo.Traversal_().WithRemote(client)
// Drop existing vertices
errChan := g.V().HasLabel("person").Drop().Iterate()
for err := range errChan {
if err != nil {
panic(fmt.Errorf("dropping all vertices: %w", err))
}
}
fmt.Println("Vertices dropped")
g2 := gremlingo.Traversal_().WithRemote(client) // New traversal instance
// Add 2 vertices initially
addVertices(g2)
fmt.Println("Vertices added")
// Channel to signal `displayVertices` to stop
done := make(chan struct{})
// Start a goroutine to display vertices
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
displayVertices(g, done)
}()
g3 := gremlingo.Traversal_().WithRemote(client)
// Begin transaction
transaction := g3.Tx()
traversal, err := transaction.Begin()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Begin")
// Drop all persons inside the transaction
errChan = traversal.GetGraphTraversal().V().HasLabel("person").Drop().Iterate()
for err := range errChan {
if err != nil {
err2 := transaction.Rollback()
if err2 != nil {
fmt.Println(err2)
return
}
}
}
// Add vertices within the transaction
addVertices(traversal)
// Commit the transaction
errCommit := transaction.Commit()
if errCommit != nil {
fmt.Println(fmt.Errorf("committing transaction: %w", errCommit))
}
// Stop the vertex display loop
close(done)
wg.Wait()
}
func displayVertices(g *gremlingo.GraphTraversalSource, done <-chan struct{}) {
for {
select {
case <-done:
fmt.Println("Stopping vertex display.")
return
default:
query := g.V().HasLabel("person").Id()
result, err := query.ToList()
if err != nil {
log.Printf("Error retrieving vertices: %v", err)
time.Sleep(time.Second)
continue
}
fmt.Println("Display all vertices")
for _, res := range result {
fmt.Printf("%v\n", res.Data.(string))
}
fmt.Println("Done displaying")
}
}
}
func addVertices(g *gremlingo.GraphTraversalSource) {
traversal := g.GetGraphTraversal().AddV("person").Property(gremlingo.T.Id, "Foo").Fold().AddV("person").Property(gremlingo.T.Id, "Bar").Fold()
fmt.Println(Translate(traversal))
errChan := traversal.Iterate()
for err := range errChan {
if err != nil {
fmt.Println(fmt.Sprintf("Error adding initial vertices: %v", err))
}
}
}
func Translate(traversal *gremlingo.GraphTraversal) string {
if traversal == nil || traversal.Bytecode == nil {
return ""
}
translator := gremlingo.NewTranslator("g")
queryTranslation, err := translator.Translate(traversal.Bytecode)
if err != nil {
// Should we care about translation failures from a client perspective?
panic(err)
}
return queryTranslation
}
Upvotes: 1
Views: 43