Why is Node-Neo4j not properly setting data?

80 Views Asked by At

Imagine a query like this:

match (i:QuestionOrder) 
set i.count=i.count+1 
merge (q:Question {text: '+text here+', index: i.count}) 
return q

Neo4j guarantees write locks if sets occur within the same transaction which is implied by the same query in node-neo4j. However, I'm getting the following output:

[
  {
    "columns":["q"],
    "data":[{"text":"Have Kids...","index":1,"_id":542}]
  },
  {
    "columns":["q"],
    "data":[{"text":"You are...","index":1,"_id":545}]
  }
]

From my understanding, a lock should prevent index from being the same. Am I missing something here? How can I resolve this?

1

There are 1 best solutions below

0
Michael Hunger On

Probably it helps for concurrent work to change this query to add an additional test. If you have two concurrent transactions, the lock is grabbed at the set-operation. So both have already read i.count and are waiting with the same value.

So either you grab that lock earlier:

match (i:QuestionOrder) 
set i.lock = NOT i.lock
set i.count=i.count+1 
merge (q:Question {text: '+text here+', index: i.count}) 
return q

or you add an additional check that avoids the merge to happen (then you have to retry)

match (i:QuestionOrder) 
WITH i, i.count + 1 as new_count
set i.count = new_count
WITH i, new_count
WHERE i.count = new_count
merge (q:Question {text: '+text here+', index: i.count}) 
return q

Or send two different statements in the same tx of which the first does the locking.