Neo4j死锁

时间:2014-02-26 02:43:18

标签: database neo4j deadlock

我正在为BG benchmark实施一个Neo4j客户端。有11个功能,模拟11种不同的社交网络动作。这些函数中的每一个都有自己的事务体。但是当我运行100个线程时,有时会抛出死锁检测异常。

我将用户作为节点和友谊作为关系。我邀请朋友,拒绝朋友,接受朋友,解冻所有有两个用户的友谊作为他们的输入。他们的工作方式是获得一个用户节点的所有关系,并找到与其他用户节点的关系。

是否有人知道Neo4j的锁定机制?

3 个答案:

答案 0 :(得分:4)

您可以在Neo4j documentation中了解死锁。当您同时修改相同的实体(节点或关系)时,可能会出现这些情况。请注意,在修改实体时,可能会使用多个锁:例如,对于关系,将采用由关系连接的两个节点上的锁。

答案 1 :(得分:1)

默认锁定行为:

  1. 在节点或关系上添加,更改或删除属性时,将对特定节点或关系进行写锁定。
  2. 创建或删除节点时,将对特定节点进行写锁定。
  3. 创建或删除关系时,将对特定关系及其两个节点进行写锁定。
  4. 锁将被添加到事务中,并在事务完成时释放。

    1. 以最小锁定的方式设计数据库。
    2. 避免使用相同的节点,并且同一实例中的许多用户使用关系。保持这些节点和关系的最短事务处理时间。

答案 2 :(得分:0)

也许序列化并行编写查询将对您的解决方案有所帮助。在您的情况下,您具有11个功能,可以模拟11种不同的社交网络操作。在您的描述中,我认为某些动作(事务)可以按顺序执行(例如,您的朋友发送邀请后,您只能接受朋友的请求)。您可以序列化一些写事务。换句话说,某些查询将被阻止,直到之前的查询完成为止。 借助因果链接和书签,您可以序列化每个会话的操作。例如,如果您具有三个功能,sendInvitationToFriend reject friendacceptFriend。拒绝/接受交易将被阻止,直到sendInvitationToFriend交易完成。

一些代码段(neo4j-java-driver 4.1):


    List<Bookmark> bookmarks = new ArrayList<>();

    // Send Invitation.
    try ( Session session = driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).build())){
        session.writeTransaction( tx -> this.sendInvitationToFriend( tx, "friendId", "yourId"));
        savedBookmarks.add(session.lastBookmark() );
    }

    // accept the invitation 
    try (Session session = driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).withBookmarks( savedBookmarks ).build())){
        session.writeTransaction( tx -> this.acceptFriend(tx, "friendId", "yourId"));
    }

    // Create a friendship between the two people created above.
    try (Session session = driver.session(builder().withDefaultAccessMode( AccessMode.WRITE).withBookmarks(savedBookmarks ).build())) {
        session.writeTransaction( tx -> this.rejectFriend( tx, "friendId", "yourId"));
    }

您还提到模拟是某种随机的。我的建议是,您可以在程序中定义重试策略,重新尝试查询服务时间,直到运行良好为止,并让主线程在任意两次重试之间睡眠一会儿。您可以从link

中找到更多详细信息。

希望这篇文章对您有所帮助。