Neo4j:通过Java API或Cypher进行显式的悲观锁定

时间:2018-04-25 01:48:52

标签: java neo4j locking neo4j-driver

有没有办法通过Neo4J Java API或Cypher在某组节点上手动获取写锁?

examples in documentation,但仅适用于嵌入式Neo4j版本。标准Java Transaction接口不包含此类方法:https://neo4j.com/docs/api/java-driver/current/org/neo4j/driver/v1/Transaction.html

我也找不到通过Cypher的方法。

2 个答案:

答案 0 :(得分:1)

您可以通过写入节点来进行写锁定,例如通过设置或删除属性。我认为这在删除不存在的属性时也有效。

如果您安装了APOC Procedures,则可以调用apoc.lock.nodes()过程,向其传递要锁定的节点列表。

答案 1 :(得分:0)

要扩展@InverseFalcon的答案,下面是通过写入节点来写锁定的示例:

nvcc x.cu .\chapter03\hello_world.cu  -ccbin "C:\Program Files (x86)\Microsoft Visual Studio\<year >\Community\VC\Tools\MSVC\<toolset>\bin\Hostx64\x64"

该测试将创建一个标签为“ Lock”的节点。它并行启动两个任务,尝试获取节点上的写锁。每个任务在获得锁(模拟工作负载)后,将在事务中等待5秒。调试输出为:

@Test
public void testPessimisticLocking() throws InterruptedException {
    txn.execute(status -> {
        session.query("CREATE (n:Lock {uuid:'test'})", Map.of(), false);
        return null;
    });

    ExecutorService executor = Executors.newFixedThreadPool(2);
    Runnable task = () -> {
        LOG.debug("Starting task");

        txn.execute(status -> {
            long time = System.nanoTime();
            LOG.debug("Locking node with time={}", time);
            session.query("MATCH (n:Lock {uuid:'test'}) SET n.time = {0}", Map.of("0", time), false);

            LOG.debug("Query done, waiting some time...");
            try {
                Thread.sleep(5000);
            }
            catch (InterruptedException e) {
                LOG.warn("Interrupted", e);
            }
            LOG.debug("Waiting done");

            return null;
        });

        LOG.debug("Finished task");
    };

    for (int i = 0; i < 2; i++) {
        executor.execute(task);
    }

    executor.shutdown();
    executor.awaitTermination(20, TimeUnit.MINUTES);
}

在日志中,您可以看到一个任务正好在另一任务完成事务时获得了锁。