我正在为BG benchmark实施一个Neo4j客户端。有11个功能,模拟11种不同的社交网络动作。这些函数中的每一个都有自己的事务体。但是当我运行100个线程时,有时会抛出死锁检测异常。
我将用户作为节点和友谊作为关系。我邀请朋友,拒绝朋友,接受朋友,解冻所有有两个用户的友谊作为他们的输入。他们的工作方式是获得一个用户节点的所有关系,并找到与其他用户节点的关系。
是否有人知道Neo4j的锁定机制?
答案 0 :(得分:4)
您可以在Neo4j documentation中了解死锁。当您同时修改相同的实体(节点或关系)时,可能会出现这些情况。请注意,在修改实体时,可能会使用多个锁:例如,对于关系,将采用由关系连接的两个节点上的锁。
答案 1 :(得分:1)
默认锁定行为:
锁将被添加到事务中,并在事务完成时释放。
答案 2 :(得分:0)
也许序列化并行编写查询将对您的解决方案有所帮助。在您的情况下,您具有11个功能,可以模拟11种不同的社交网络操作。在您的描述中,我认为某些动作(事务)可以按顺序执行(例如,您的朋友发送邀请后,您只能接受朋友的请求)。您可以序列化一些写事务。换句话说,某些查询将被阻止,直到之前的查询完成为止。
借助因果链接和书签,您可以序列化每个会话的操作。例如,如果您具有三个功能,sendInvitationToFriend
, reject friend
,acceptFriend
。拒绝/接受交易将被阻止,直到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
中找到更多详细信息。希望这篇文章对您有所帮助。