我正在编写一个非托管扩展程序。
由于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;
}
答案 0 :(得分:1)
您的代码实际上是写入(以及读取)节点,但您只是获取读锁定。您必须使用acquireWriteLock代替。一旦你这样做,你应该摆脱"同步" (参见this section of the docs中的警告)。