【问题标题】:how to avoid deadlock in spring data neo4j ogm while saving data concurrently如何在同时保存数据的同时避免spring数据neo4j ogm中的死锁
【发布时间】:2017-08-30 18:00:54
【问题描述】:

我一直在尝试使用带有 1 个 CPU 和 1GB RAM 的 SpringDataNeo4j(SDN) 同时加载测试。 对于“GET”(读取)请求,能够测试 1000 个线程,加速时间为 1 秒。 对于“POST”(写入)请求,但只能使用 18 个线程进行测试,加速时间为 1 秒,超出此线程。我们面临死锁异常:

原因:org.neo4j.ogm.exception.CypherException:执行 Cypher “Neo.TransientError.Transaction.DeadlockDetected”时出错;代码:Neo.TransientError.Transaction.DeadlockDetected;描述:LockClient[1081] 不能等待资源 RWLock[NODE(97), hash=108078135] 因为 => LockClient[1081]

我已经提到 http://neo4j.com/docs/java-reference/current/#transactions-deadlocks

TransactionTemplate template = new TransactionTemplate(  ).retries( 5 ).backoff( 3, TimeUnit.SECONDS );

对于 saveService,我使用默认的 @Transactional,尽管我无法在我的测试代码中复制 TransactionTemplate。我使用我的 DataSourceFactory 配置。

@Configuration 
@PropertySource(value = { "classpath:ogm.properties" }
@EnableNeo4jRepositories(basePackages = "com.my.graph.repository")
@EnableTransactionManagement

任何建议!

提前致谢!

【问题讨论】:

  • 你在写测试中使用的密码语法是什么?
  • 我没有在这种情况下使用密码。我正在使用 API 扩展 GraphRepository 的 OGM 'Dao.save(node)'

标签: java multithreading neo4j spring-data spring-data-neo4j


【解决方案1】:

您可以通过以下方式减少发生死锁的可能性

  • 使交易更小 - 例如而不是保存 1000 个节点和关系,只保存 100 个

  • 使用域的结构确保您不会同时更新相同的节点

但有时无法避免。在这些情况下,您可以

  • 捕获异常并重新运行事务(本质上是自己重试)

    int retries = 5;
    while (retries > 0) {
      try {
        fooService.foo(bar);
      } catch (CypherException ex) {
        retries--;
        Thread.sleep(delay);
      }
    }
    
  • 使用一些已经实现重试逻辑的库,例如spring-retryguava-retrying

【讨论】:

  • 非常感谢!我将开始执行相同的操作。
  • 我已经按照您的建议实现了节点保存的自定义重试机制,我发现了一些改进。思想总是不一致。请求较少时仍会出现死锁
猜你喜欢
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多