「分離」を表す ACID (Neo4j は ACID 準拠) の「I」について説明する必要があります。分離のレベルは、トランザクションを同時に実行している互いのデータの量を示します。
Neo4j のデフォルトの分離レベルは「読み取りコミット」です。これは、B がコミットするまで、B が書き込んだデータが A に表示されないことを意味します。これは、次のように機能する自動ロックによって実現されます。
Neo4j は、ノードと関係を読み取るときに読み取りロックし (多くの読み取りロックを取得できます)、ノードと関係を変更するときに書き込みロックします。書き込みロックがある場合は読み取りロックを取得できず、別の書き込みロックがある場合は書き込みロックを取得できません。トランザクションがコミットされると、ロックが解放されます。
ただし、この分離レベルではいくつかの異常が発生する可能性があり、そのうちの 1 つは「失われた更新」と呼ばれます。
説明のために、c をカウンター値とします (アトミック カウンターが最終的に求められるものであることは理解しています)。どちらのトランザクションも、カウンターを 1 ずつ増やしています。
c=0
Tx1 reads c=0 (read locks c)
Tx2 reads c=0 (read locks c)
Tx1 writes c=1 (write locks c)
Tx1 commits (unlocks c)
Tx2 writes c=1 (because it thinks c is still 0, write locks c)
Tx2 commits (unlocks c)
Tx1 が行った更新は失われます。
これを防ぐには、現在の値を読み取る前に、明示的に変更するオブジェクトを事前に書き込みロックして、分離レベルを「反復可能な読み取り」に変更する必要があります。このようにして、同時に実行されている他のトランザクションによって変更されることはありません。
c=0
Tx1 write locks c
Tx1 reads c=0
Tx2 tries to write lock c, has to wait
Tx1 writes c=1
Tx1 commits (unlocks c)
Tx2 write locks c (because it now can)
Tx2 reads c=1
Tx2 writes c=2
Tx2 commits (unlocks c)
物事がより明確になることを願っています。