简体   繁体   English

Neo4j图形操作在多线程环境中

[英]Neo4j graph operations in a multithreaded environment

I'm using Neo4j in a concurrent environment and I have graph that looks like this: 我在并发环境中使用Neo4j,我的图形看起来像这样:

图形

Each item can be in none or at most one of 3 states ( S1 , S2 and S3 ). 每个项目可以是3个状态( S1S2S3 )中的任何一个或最多中的一个。 An item can change its state and the flow goes this way: item is not present in any state, then S1 , S2 and finally S3 . 一个项目可以改变它的状态,流程就是这样:项目不存在于任何状态,然后是S1S2 ,最后是S3

This means that when adding an item I will have to check whether it's already present in S1 , S2 or S3 . 这意味着在添加项目时,我必须检查它是否已经存在于S1S2S3 If it is, then I shouldn't add it again. 如果是,那么我不应该再添加它。 Additionally, if the item is in S1 and is requested to go to the next state in the flow then the item must be first removed from S1 and then added to S2 . 此外,如果项目在S1并且被要求转到流程中的下一个状态,则必须首先从S1删除该项目,然后将其添加到S2

Having an index on each of the states wouldn't solve this issue because all of these operations must happen atomically as it is a concurrent environment. 对每个状态建立索引都无法解决此问题,因为所有这些操作必须以原子方式发生,因为它是并发环境。 I've checked this link and I could only think about going for the Pessimistic locking approach. 我已经检查了这个链接 ,我只能考虑采用悲观锁定方法。 The pseudocode to add a new item, based on the example, should be something like: 根据示例添加新项目的伪代码应该类似于:

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

The pseudocode to change from a state to another state should be very similar to the previous one. 从状态变为另一个状态的伪代码应该与前一个非常相似。

So the questions are: 所以问题是:

  1. What is #lockNode# in my pseudocode? 我的伪代码中的#lockNode#是什么? I can't figure it out from the example. 我无法从这个例子中弄清楚。 Sounds like it similar to a synchronized (lockNode) {} but I need a little exaplanation to go on with this solution 听起来像是一个类似于synchronized (lockNode) {}但是我需要一点点说明来继续这个解决方案
  2. What would be the impact of using the reference node as #lockNode#? 使用引用节点作为#lockNode#会有什么影响?
  3. Is it possible to atomically and in a sychronized way perform the searches in the three indexes and then add/move the node to a state? 是否有可能以原子方式和同步方式执行三个索引中的搜索,然后将节点添加/移动到某个状态?

I could easily solve this by using Java synchronization but the documentation clearly states this should not be done. 我可以通过使用Java同步轻松解决这个问题,但文档清楚地说明不应该这样做。 Any help for a Neo4j newbie like me would be appreciated. 任何像我这样的Neo4j新手的帮助将不胜感激。

As an item can only be in one state, you can have only one index and use the "Get or create" technique in the link you provided. 由于项目只能处于一种状态,因此您只能拥有一个索引,并在您提供的链接中使用“获取或创建”技术。 To know the state of an item you can traverse the dingle relationship then the state node. 要知道项目的状态,您可以遍历丁当关系,然后是状态节点。 Or you can index using 2 properties (name & state). 或者您可以使用2个属性(名称和状态)进行索引。 Or have 4 indexes 或者有4个索引

Locking the reference node will create a bottleneck (a bit less if you lock only the s1 node), and for unique node creation I think the best way is the get-or-create thing, I don't know any other good way 锁定引用节点将产生瓶颈(如果仅锁定s1节点则会少一点),对于唯一节点创建,我认为最好的方法是获取或创建的东西,我不知道任何其他好方法

Synchronization is also a big no-no as it can "conflict" with the neo4j internal locking system and create dead-locks 同步也是一个很大的禁忌,因为它可以与neo4j内部锁定系统“冲突”并创建死锁

Lock-Node in your code is either `lockNode.removeProperty("__non_existing_property") or explicitly grabbing a lock via the transaction. 代码中的锁定节点是`lockNode.removeProperty(“__ non_existing_property”)或通过事务显式获取锁定。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM