title: Locking mechanism on Neo4J
body: <p>I found a concurrent issue on my application where there are two threads that try to do write operation in same time on same node or relationship in Neo4J v2.2.5.</p>
  
  <p>I managed to reproduce the issue using simple way:</p>
  
  <ol>
  <li><p>Download and import example neo4j movie database: <a href="http://example-data.neo4j.org/files/cineasts_12k_movies_50k_actors_2.1.6.zip" rel="nofollow">http://example-data.neo4j.org/files/cineasts_12k_movies_50k_actors_2.1.6.zip</a>
  Since the database is old, so you have to add <code>allow_store_upgrade=true</code> in <code>conf/neo4j.properties</code> to enable auto database upgrade.</p></li>
  <li><p>Start the neo4j and run this query on neo4jshell:</p>
  
  <pre><code>match (a:Actor {name: "Claude Jade"}), (m:Movie)
  merge (a)-[:ACTS_IN]-&gt;(m);
  </code></pre>
  
  <p>This will create ACTS_IN relationship from the "Claude Jade" Actor to all Movie nodes. The reason of doing this is to make the delete "Claude Jade" Actor node process (see no. 4 below) more longer so the chance of concurrent issue happening is more bigger.</p></li>
  <li><p>Download curl command-line program if you don't have it yet. We will use curl to send query to neo4j.</p></li>
  <li><p>Create a bash script file (filename is up to you) with content:</p>
  
  <pre><code>#!/bin/bash
  
  curl -XPOST http://localhost:7474/db/data/transaction/commit -H "Content-Type: application/json" -d '{"statements" : [ {"statement" : "MATCH (n:Actor {name: \"Claude Jade\"}) OPTIONAL MATCH (n)-[r]-() DELETE n, r"} ]}' &amp;
  curl -XPOST http://localhost:7474/db/data/transaction/commit -H "Content-Type: application/json" -d '{"statements" : [ {"statement" : "MATCH (n:Actor {name: \"Claude Jade\"}) CREATE (n)-[:ACTS_IN]-&gt;(m:Movie {title: \"Hello World\"}) RETURN m"} ]}' &amp;
  
  wait
  </code></pre>
  
  <p>This will run two curl process in parallel where the 1st process will try to delete the "Claude Jade" Actor and all of its relationships, and the 2nd process will try to create new ACTS_IN relationship to the "Claude Jade" Actor.</p></li>
  <li><p>Run the script file on bash, e.g. <code>$ ./test.sh</code></p></li>
  </ol>
  
  <p>Here is the result I got:</p>
  
  <pre><code>{
      "results" : [{
              "columns" : ["m"],
              "data" : [{
                      "row" : [{
                              "title" : "Hello World"
                          }
                      ]
                  }
              ]
          }
      ],
      "errors" : []
  } {
      "results" : [{
              "columns" : [],
              "data" : []
          }
      ],
      "errors" : [{
              "code" : "Neo.DatabaseError.Transaction.CouldNotCommit",
              "message" : "org.neo4j.kernel.api.exceptions.TransactionFailureException: Node record Node[3150,used=false,group=55,prop=-1,labels=Inline(0x0:[]),light] still has relationships",
              "stackTrace" : "java.lang.RuntimeException: org.neo4j.kernel.api.exceptions.TransactionFailureException: Node record Node[3150,used=false,group=55,prop=-1,labels=Inline(0x0:[]),light] still has relationships\r\n\tat org.neo4j.server.rest.transactional.TransitionalTxManagementKernelTransaction.commit(TransitionalTxManagementKernelTransaction.java:87)\r\n\tat org.neo4j.server.rest.transactional.TransactionHandle.closeContextAndCollectErrors(TransactionHandle.java:278)\r\n\tat 
              ...
  </code></pre>
  
  <p>Note: if you don't see any transaction error, then you have to reimport again the movie database and re-run the steps above.</p>
  
  <p>So from what I've seen, the deletion failed because it tried to delete the Actor node and its of all of ACTS_IN relationships, it did the MATCH query first (<code>MATCH (n:Actor {name: \"Claude Jade\"}) OPTIONAL MATCH (n)-[r]-()</code>) but before it executed the <code>DELETE n, r</code>, the 2nd process managed to insert the new ACTS_IN relationship to the Actor node so that's why the deletion failed because when it did try to execute the DELETE, the Actor already have one new relationship added.</p>
  
  <p>I wonder if there is locking mechanism on Neo4J that can be used to prevent this issue?</p>