curious
curious

Reputation: 11

Issue with Transactions in Local TinkerPop Gremlin Setup

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

Answers (0)

Related Questions