首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在同一事务中锁定的节点之间创建关系的Neo4j死锁

在同一事务中锁定的节点之间创建关系的Neo4j死锁
EN

Stack Overflow用户
提问于 2014-08-06 21:35:53
回答 1查看 1.2K关注 0票数 3

我的Neo4j服务器在执行并发请求时抛出DeadlockDetectedExceptions,我不知道为什么。

以下代码由客户端REST请求调用的服务器插件调用,并在单个事务中发生。

代码语言:javascript
复制
  Node nFollowing = loadUser(idFollowing);
  Node nFollowed = loadUser(idFollowed);

  // locking order to avoid deadlocks
  if (Long.valueOf(idFollowing) < Long.valueOf(idFollowed)) {
    tx.acquireWriteLock(nFollowing);
    tx.acquireWriteLock(nFollowed);
  } else {
    tx.acquireWriteLock(nFollowed);
    tx.acquireWriteLock(nFollowing);
  }

  // create relationship if not present
  for (Relationship followship : nFollowing.getRelationships(
    EdgeType.FOLLOWS, Direction.OUTGOING)) {
    if (followship.getEndNode().equals(nFollowed)) {
      return;
    }
  }
  nFollowing.createRelationshipTo(nFollowed, EdgeType.FOLLOWS);

尽管我考虑了死锁,但抛出了以下异常,表明在创建关系时发生了死锁。

异常(略微减少):

代码语言:javascript
复制
"ForsetiClient[78] can't acquire ExclusiveLock{owner=ForsetiClient[73]} on  
  RELATIONSHIP(49), because holders of that lock are waiting for ForsetiClient[78].\n
  Wait list:ExclusiveLock[ForsetiClient[73] waits for [73, 78, ]]",
"exception" : "DeadlockDetectedException",
"fullname" : "org.neo4j.kernel.DeadlockDetectedException",
"stacktrace" : [
  "org.neo4j.kernel.ha.lock.forseti.ForsetiClient.markAsWaitingFor(ForsetiClient.java:611)",
  "org.neo4j.kernel.ha.lock.forseti.ForsetiClient.acquireExclusive(ForsetiClient.java:190)",
  "org.neo4j.kernel.impl.nioneo.xa.TransactionalRelationshipLocker.getWriteLock(TransactionalRelationshipLocker.java:33)",
  "org.neo4j.kernel.impl.core.NodeProxy.createRelationshipTo(NodeProxy.java:455)",
  "de.uniko.sebschlicht.neo4j.graphity.WriteOptimizedGraphity.addFollowship(WriteOptimizedGraphity.java:40)",
  "de.uniko.sebschlicht.neo4j.graphity.Graphity.addFollowship(Graphity.java:115)",
  "de.uniko.sebschlicht.neo4j.GraphityBaselinePlugin.follow(GraphityBaselinePlugin.java:38)",
  "org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension(ExtensionService.java:134)",
  "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)"
]

我不明白为什么:我已经有了nFolloingnFollowed的锁。实际上,死锁的目标不是节点锁,而是关系锁。由于仅在关系不存在时创建关系,因此锁持有者必须是当前锁持有者。

如果这是正确的,锁持有者正在等待自己。我该如何避免这种情况,或者异常还想说些什么呢?

以防万一:我不想使用synchronized块,它是suggested,也是marked as to be avoided by Neo4j,因为它会大大减慢我的服务速度,而且我不希望这些并发请求经常发生。

EN

回答 1

Stack Overflow用户

发布于 2014-09-18 21:56:36

死锁是由snychronized块和手动事务锁共同引起的。我没有从之前执行的测试中删除synchronized语句。尽管synchronized语句没有针对锁定的节点,但还是引发了异常。这两种锁定机制似乎是不兼容的。

这导致了一个奇怪的错误消息,对我来说帮助不大。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25161837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档