2015-05-07 45 views
2

首先我將解釋爲什麼我想手動設置寫鎖。我在基於Spring Data Neo4j的Web服務應用程序中使用Neo4j數據庫。事務由Spring管理,我只使用@Transactional註釋。但是,我遇到了導致數據庫不一致的特定用例的問題。我有是事務性的方法,其目的是使這樣的節點/關係數據庫:如何在Spring管理事務中手動管理Neo4j鎖

(對:人) - [:用途] - >(S:SIM_Card {電話號碼: 「XXX」})

它的算法如下:

如果沒有與特定的電話號碼(唯一的)一個SIM_Card

-check已經在數據庫中(通過@Query暗號查詢),

- 如果是得到這個節點,如果沒有創建它,

- 檢查是否有任何人連接到此SIM_具有使用關係的卡片(密碼查詢),

- 如果沒有這樣的人員創建並附加到SIM_Card。

不幸的是,當有很多請求時,它發生在我連接到多個Person的數據庫SIM_Cards中。我假設該方法由兩個併發線程執行。兩者都讀取數據庫並使用相同的電話號碼搜索SIM_Card,並且都獲得數據庫中沒有此類SIM_Card的信息,因此他們創建它們,然後將兩個單獨的Person附加到它們。 PhoneNuber對於SIM_Card來說是唯一的,所以最終只有一個SIM_Card,但是兩個人仍然存在,這不是預期的情況。 要解決這個問題,我想在單獨的事務中創建SIM_Card,然後創建Person並在另一個事務中附加到此SIM_Card。在創建人員之前,我將檢查是否沒有人員已經連接。但是,在此之前,我想在SIM_Card上手動設置寫入鎖,並且假設其他交易將無法在此期間檢查是否有/或沒有任何人連接到此SIM_Card。它將不得不等待鎖被釋放,然後它會看到這個SIM_Card已經連接了Person,並且不會創建另一個。

爲了實現這一點,我必須設法在@Transactional註釋方法中設置Neo4j鎖,並且我不知道該怎麼做。我將衷心感謝您的幫助。

+0

你有沒有發現這種情況下的解決方案?目前我碰到同樣的問題,不知道如何獲得寫鎖定,以便正確更新我的計數器。 – alexanoid

回答

0

我認爲你必須放棄@Transactional在這種情況下,電線GraphDatabaseService實例到你的倉庫(或服務),並啓動交易並手動獲取寫入鎖定(http://neo4j.com/docs/stable/javadocs/org/neo4j/graphdb/Transaction.html#acquireWriteLock(org.neo4j.graphdb.PropertyContainer)

+0

我的第一個想法是獲取當前事務並使用它來獲取鎖。但是,我找不到通過@Transactional開始訪問正在進行的事務的方式。因此,我放了這樣的事情:\t事務t = graphDatabaseService.beginTx();來獲得任何事務,但是,我不太確定會發生什麼當我把這裏面的交易方法。在日誌中,我甚至沒有在DEBUG級別上看到任何東西。當我把它們放在新交易或甚至鎖定時什麼都沒有。沒有日誌,沒有錯誤,我不知道它是否有效,因爲它很難檢查。 – Cob

+0

@Cob你有沒有找到這種情況下的解決方案?目前我遇到了同樣的問題,不知道如何獲得寫鎖定,以便正確更新我的計數器。 – alexanoid