3

我在并发环境中使用 Neo4j,我的图表如下所示:

图形

每个项目可以不处于或最多处于 3 种状态(S1S2S3中的一种。一个项目可以改变它的状态,流程是这样的:项目在任何状态下都不存在,然后S1S2最后S3

这意味着当添加一个项目时,我必须检查它是否已经存在于S1,S2S3. 如果是,那么我不应该再次添加它。此外,如果项目在S1并且被请求进入流中的下一个状态,则必须首先从 中删除该项目S1,然后再将其添加到S2

对每个状态都有一个索引并不能解决这个问题,因为所有这些操作都必须以原子方式发生,因为它是一个并发环境。我已经检查了这个链接,我只能考虑采用悲观锁定方法。基于示例添加新项目的伪代码应类似于:

search for node in all states
if node is present in any state
    return node
else
    begin transaction
        get a write lock on #lockNode#
        create node
        add node to initial state
    commit
    return node
end

从一种状态变为另一种状态的伪代码应该与前一个非常相似。

所以问题是:

  1. 我的伪代码中的#lockNode# 是什么?我无法从示例中弄清楚。听起来类似于 asynchronized (lockNode) {}但我需要一些解释才能继续使用此解决方案
  2. 将参考节点用作#lockNode# 会有什么影响?
  3. 是否可以以原子方式和同步方式在三个索引中执行搜索,然后将节点添加/移动到某个状态?

我可以通过使用 Java 同步轻松解决这个问题,但文档明确指出不应该这样做。对像我这样的 Neo4j 新手的任何帮助将不胜感激。

4

2 回答 2

1

由于一个项目只能处于一种状态,因此您只能拥有一个索引并在您提供的链接中使用“获取或创建”技术。要了解项目的状态,您可以遍历 dingle 关系,然后遍历状态节点。或者您可以使用 2 个属性(名称和状态)进行索引。或者有 4 个索引

锁定参考节点会造成瓶颈(如果只锁定 s1 节点会少一点),对于唯一节点创建,我认为最好的方法是 get-or-create ,我不知道还有什么其他好的方法

同步也是一个很大的禁忌,因为它可能与 neo4j 内部锁定系统“冲突”并产生死锁

于 2012-10-03T07:11:23.007 回答
0

代码中的 Lock-Node 是 `lockNode.removeProperty("__non_existing_property") 或通过事务显式获取锁。

Transaction tx = graphDb.beginTx();
try {
    tx.acquireWriteLock( lockNode );
    // do something
    tx.success();
}
finally {
    tx.finish();
}

来自 Neo4j 手册: http ://docs.neo4j.org/chunked/snapshot/transactions-unique-nodes.html

于 2012-10-07T21:08:17.207 回答