Hi all
We're starting to look in more detail at the new Cypher transaction
endpoint in Neo4j 2.0. The docs state that transactions operate with write
locks <http://docs.neo4j.org/chunked/stable/transactions-locking.html> and
that the default isolation level is READ
COMMITTED<http://docs.neo4j.org/chunked/stable/transactions-isolation.html>.
Given that neither locks nor isolation levels are supported over REST,
we're uncertain how best to handle a situation where two concurrent
transactions attempt to both read and write the same property value.
As an example, let's assume that we want to make a deposit into a bank
account with an initial balance of zero. Each client thread carries out the
following sequence of actions:
BEGIN
EXECUTE: *MATCH (a:Account {no:123456}) SET a.balance = a.balance + 20
RETURN a.balance*
COMMIT
If these are carried out in series and one commits before the other starts,
then all works as expected and a total of 40 is deposited into the account.
If however, these operate concurrently, we can get a situation like this:
BEGIN 1
BEGIN 2
EXECUTE 1: *MATCH (a:Account {no:123456}) SET a.balance = a.balance + 20
RETURN a.balance*
EXECUTE 2: *MATCH (a:Account {no:123456}) SET a.balance = a.balance + 20
RETURN a.balance*
COMMIT 1
COMMIT 2
In this case, the second update overwrites the first and we end up losing
one of the deposits. From investigation with the core API, my understanding
is that both statements create a write lock on the node and the *read* part
of the SET statement executes but the *write* part blocks until this lock
is released. Therefore, both statements end up adding 20 to a balance of
zero instead of to the value of the property after the write lock has been
released.
All of which means that there is the potential for some every unexpected
behaviour when using REST transactions. In the core API, it is of course
possible to manually create a read lock on the node preventing this from
happening. Should this facility somehow be added to the REST API? Another -
slightly more specific - solution could be the introduction of an atomic +=
operator. Although this might not help in all such cases.
Thoughts and feedback very welcome. And I'm happy to be told that I've
missed something obvious :-)
Nige
--
You received this message because you are subscribed to the Google Groups
"Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.