2016-12-09 59 views
2

我在寫一個非託管擴展。如何在Neo4j中創建唯一的序列號?

因爲Neo4J沒有任何內置功能來獲取序列號我寫這個方法來實現類似的功能。它與「synchronized」關鍵字一起工作正常,但沒有它,當我嘗試在一個測試用例中使用它時,我得到了一個DeadlockDetectedException,我在同一時間從多個線程調用它。

這是解決此問題的好方法嗎?

爲什麼我需要使方法「同步」,不應該「acquireReadLock」是否足夠?

public synchronized static int getNextSequence(Node node, String property) { 
    int sequence = 0; 
    GraphDatabaseService graphDb = node.getGraphDatabase(); 

    try(Transaction t = graphDb.beginTx()) { 
     t.acquireReadLock(node); 

     sequence = (int) node.getProperty(property); 
     node.setProperty(property, sequence + 1); 

     //The lock is automatic released on t.success(). 
     t.success(); 
    } catch (Exception e) { 
     log.error("Failed to get sequence for node: ({}), property: ({}), exception: ({})", node, property, e); 
     throw e; 
    } 

    return sequence; 
} 

編輯
從@cybersam響應後,我改變acquireReadLock到acquireWriteLock它解決了DeadlockProblem問題,我不再需要進行同步的方法。

更新的代碼看起來是這樣的:

public static int getNextSequence(Node node, String property) { 
    int sequence = 0; 
    GraphDatabaseService graphDb = node.getGraphDatabase(); 

    try(Transaction t = graphDb.beginTx()) { 
     t.acquireWriteLock(node); 

     sequence = (int) node.getProperty(property); 
     node.setProperty(property, sequence + 1); 

     //The lock is automatic released on t.success(). 
     t.success(); 
    } catch (Exception e) { 
     log.error("Failed to get sequence for node: ({}), property: ({}), exception: ({})", node, property, e); 
     throw e; 
    } 

    return sequence; 
} 

回答

1

你的代碼是實際寫入(以及讀取)的節點,但你只能獲取一個讀鎖定。您必須改用acquireWriteLock。一旦你這樣做,你應該擺脫「同步」(請參閱​​this section of the docs中的警告)。

+0

你是絕對正確的,謝謝。 :) –