1

I have some code that needs to acquire a write lock on a node. For various reasons it is inconvenient to use the Java API to acquire the lock, so I acquired it in Cypher 2.1 by setting a dummy value on the node. Then I use the node in a different query. In 2.1, calling SET n._lock = 1 was sufficient to acquire a write lock on the node for the rest of the transaction. However, when I upgrade to 2.2, I have a test that fails, because the write lock appears to be lost between queries within the same transaction. (I'm using Neo4j Community edition in embedded mode.)

So I have two queries like so (in the same TX):

    MATCH (a:A)
    WHERE ID(a) = {aId}
    SET a._lock = 1

    MATCH (a:A)
    WHERE ID(a) = {aId}
    WITH a
    MATCH (b:B)-[:IS_AT]->(a:A)
    ...  // then more application code in the same TX

I have a unit test that calls this code multiple times in parallel and verifies a mutex property of the later code, ie. the later code was not run in parallel due to the write lock in the first query (there is only one "A" node in the test). This test passes in 2.1, but fails in 2.2. If I modify the second query to be like

    MATCH (a:A)
    WHERE ID(a) = {aId}
    SET a._lock = 1
    WITH a
    MATCH (b:B)-[:IS_AT]->(a:A)
    ...

The test passes. This seems to be evidence that the TX "loses" the write lock between the first and second query, which is disturbing. Can anyone explain this behavior?

Jonathan Crosmer
  • 786
  • 5
  • 19
  • Jonathan, how do you execute those? Perhaps you can share the full code? Remember that transactions are threadbound! – Michael Hunger Aug 10 '15 at 11:29
  • It would be amazing if you could provide a failing unit-test for this. – Michael Hunger Aug 10 '15 at 11:29
  • Opened this issue: https://github.com/neo4j/neo4j/issues/5091 As I mentioned in that issue it could be tricky to provide you a test case, since unfortunately there are a lot of dependencies. But I will see what I can do. – Jonathan Crosmer Aug 10 '15 at 15:31
  • Where I mention the two queries are in the same TX, they are in fact run in the same thread, in the same method one right after the other. As far as I can tell the only difference from the second version is that the lock is acquired in the same query as the mutex check is performed (in the second version, only "SET a._lock = 1" just before the WITH clause was added). Now that I have confirmation this is not somehow expected behavior, I will try to come up with more helpful debugging info. – Jonathan Crosmer Aug 10 '15 at 15:31
  • Do you actually start an outer tx for those two queries? Otherwise they will run in two separate transactions !!! Even if they are in the same thread. – Michael Hunger Aug 11 '15 at 12:56
  • Yes, both queries together are wrapped in a single TX. I'm debugging right now and may be on to something... I'll post further details in the Neo4j Github issue linked above soon – Jonathan Crosmer Aug 11 '15 at 13:52

0 Answers0