Neo4j cq驱动程序失败,显示“无法识别的事务ID。 交易可能已超时并已回滚。”

I have recently moved our staging environment from a neo4j 2.2.2 community edition docker container to a 2.3.0-RC1 HA cluster.

This go script provides an API end-point for authenticated users to upload a csv file which then gets processed in a way that it matches the id of a product (upc) with the existing product data. On a match the user's associated distributor creates a relationship to the found product and adds information available in the csv file onto that created relationship.

My problem is that I'm getting a failure from Neo4j in the new environment that I can't track down: "Unrecognized transaction id. Transaction may have timed out and been rolled back." when the user tries to upload the file.

Here's the complete script (my second golang script, so pointers on style are welcome, too).

package main

import (
    "database/sql"
    "encoding/csv"
    "fmt"
    _ "gopkg.in/cq.v1"
    _ "gopkg.in/cq.v1/types"
    "net/http"
    "os"
    "strconv"
    "strings"
)

type ProductInfo struct {
    Upc       uint64
    InStock   uint64
    BasePrice float64
    LeadMin   uint64
    LeadMax   uint64
    Sku       string
}

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    file, _, err := r.FormFile("file")

    if err != nil {
        fmt.Fprintln(w, err)
        return
    }

    defer file.Close()

    distributor := strings.Split(r.URL.Path, "/")[2]

    reader := csv.NewReader(file)
    reader.FieldsPerRecord = 6
    reader.TrimLeadingSpace = true

    rawCSVdata, err := reader.ReadAll()

    if err != nil {
        fmt.Fprintln(w, err)
        return
    }

    db, err := sql.Open("neo4j-cypher", os.Getenv("MINAMI_NEO4J_URL"))
    if err != nil {
        fmt.Fprintln(w, err)
        return
    }
    defer db.Close()

    tx, err := db.Begin()
    if err != nil {
        fmt.Fprintln(w, err)
        return
    }

    stmt, err := tx.Prepare(`
        MATCH (d:Distributor {slug:'` + distributor + `'})
        MATCH (p:Product {upc: {0}})
        MERGE (d)-[r:SELLS]->(p)
        SET r.inStock = {1}, r.sellsFor = {2}, r.leadMin = {3}, r.leadMax = {4}, r.sku = {5}
        RETURN p LIMIT 1
    `)

    if err != nil {
        fmt.Fprintln(w, err)
        return
    }

    var Row ProductInfo

    for _, each := range rawCSVdata {
        Row.Upc, _ = strconv.ParseUint(each[0], 10, 0)
        Row.InStock, _ = strconv.ParseUint(each[1], 10, 0)
        Row.BasePrice, _ = strconv.ParseFloat(each[2], 0)
        Row.LeadMin, _ = strconv.ParseUint(each[3], 10, 0)
        Row.LeadMax, _ = strconv.ParseUint(each[4], 10, 0)
        Row.Sku = each[5]

        stmt.Exec(Row.Upc, Row.InStock, Row.BasePrice, Row.LeadMin, Row.LeadMax, Row.Sku)
    }

    err = tx.Commit()
    if err != nil {
        fmt.Fprintln(w, err)
        return
    }

    fmt.Fprintf(w, "File uploaded and products in store updated.")
}

func main() {
    http.HandleFunc("/", uploadHandler)
    http.ListenAndServe(":8888", nil)
}

I'm using haproxy to know who's master and who are the slaves in the HA cluster. The environment variable MINAMI_NEO4J_URL is set to the master via haproxy in this form: http://{haproxyip}:{masterport}