2013-08-28 89 views
4

我對於期限交易有點混淆。 假設在交易A中我們有兩個命令C1和C2,在交易B中也是一樣。 現在兩個交易都在同一時間,然後 這些觀察結果是否正確?交易在參考neo4j數據庫時意味着什麼

  1. 事務A C1和C2的所有命令將首先完成(假設A先輸入),則只執行事務B的命令。

  2. 可以執行事務A或B的任何命令,但可以保證如果任何事務的任何命令失敗,那麼該事務將回滾。

  3. 如果第二種情況爲真,那麼在默認情況下交易,但不鎖定任何資源,直到其完成

  4. 如果第一種情況爲真,那麼默認的事務保持鎖定在資源,直到其完成。

感謝

阿米特AGGARWAL

回答

7

我們需要談談 「我」 在ACID(Neo4j的是ACID兼容),代表 「隔離」。隔離級別告訴你,同時運行事務的對方數據量有多少。

Neo4j中的默認隔離級別是「已讀提交」。這意味着A不會看到B寫入的數據,直到B提交。這是通過自動鎖定實現的,其工作原理如下:

Neo4j在您讀取它們(您可以獲取多個讀取鎖)時讀取鎖定節點和關係,並在修改節點和關係時對其進行寫入鎖定。存在寫入鎖定時無法獲取讀取鎖定,並且存在另一個寫入鎖定時無法獲取寫入鎖定。事務提交時會釋放鎖。

但是,在此隔離級別會發生一些異常情況,其中之一稱爲「丟失更新」。爲了說明,讓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) 

希望讓事情更清楚。

+0

任何人都知道如何做這個寫鎖定? (在Cypher查詢/ Neography中) – mirelon

+0

恐怕現在不可能使用Cypher來顯式獲取鎖。唯一的方法就是核心API(Java)。 –

+1

這有點麻煩,但是你可以使用Cypher來明確獲取節點或關係上的寫鎖。您可以通過在節點/關係上臨時設置一次性屬性來獲取一個。然後,在查詢結束之前,您可以刪除一次性屬性。 – cybersam