我在并发环境中使用Neo4j,我的图形看起来像这样:
每个项目可以是3种状态(S1
,S2
和S3
)中的任何一种,也可以是最多一种。项目可以更改其状态,流程也是如此:项目不在任何状态,然后是S1
,S2
,最后是S3
。
这意味着在添加项目时,我必须检查它是否已经存在于S1
,S2
或S3
中。如果是,那么我不应该再添加它。此外,如果该项目位于S1
并且要求转到流程中的下一个状态,则必须先从S1
移除该项目,然后将其添加到S2
。
对每个状态建立索引都无法解决此问题,因为所有这些操作必须以原子方式发生,因为它是并发环境。我已经检查了this link,我只能考虑采用悲观锁定方法。根据示例添加新项目的伪代码应该类似于:
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
从状态变为另一种状态的伪代码应该与前一种状态非常相似。
所以问题是:
synchronized (lockNode) {}
类似,但我需要一点点的解释来继续这个解决方案我可以通过使用Java同步轻松解决这个问题,但文档明确指出不应该这样做。对像我这样的Neo4j新手的任何帮助都将不胜感激。
答案 0 :(得分:1)
由于项目只能处于一种状态,因此您只能拥有一个索引,并在您提供的链接中使用“获取或创建”技术。要知道项目的状态,您可以遍历丁当关系,然后是状态节点。或者您可以使用2个属性(名称和状态)进行索引。或者有4个索引
锁定引用节点将产生瓶颈(如果仅锁定s1节点则会少一点),对于唯一节点创建,我认为最好的方法是获取或创建的东西,我不知道任何其他好方法
同步也是一个很大的禁忌,因为它可以与neo4j内部锁定系统“冲突”并创建死锁
答案 1 :(得分:0)
代码中的锁定节点是`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