如何在Neo4j中创建一个唯一的序列号?

时间:2016-12-09 15:37:32

标签: java neo4j thread-safety

我正在编写一个非托管扩展程序。

由于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 个答案:

答案 0 :(得分:1)

您的代码实际上是写入(以及读取)节点,但您只是获取读锁定。您必须使用acquireWriteLock代替。一旦你这样做,你应该摆脱"同步" (参见this section of the docs中的警告)。