如何在弹簧数据中避免死锁Neo4J OGM,同时同时保存数据



我一直在尝试使用带有1个CPU和1GB RAM的SpringDataneo4J(SDN)同时加载测试。对于"获取"(读取)请求,可以用1秒的速度测试1000个线程。对于"帖子"(写)请求,但只能用18个线程进行1秒的18个线程测试,超出了该线程。我们面临僵局例外:

由:org.neo4j.ogm.m.exception.cypherexception:执行Cypher" neo.transienterror.transaction.deadlockdetected"的错误。代码:neo.transienterror.transaction.deadlockdetected;描述:Lockclient [1081]等不及资源rwlock [node(97),哈希= 108078135]自=> lockclient [1081]< - [:held_by] - rwlock [node(98),哈希= 1267379687]< - [:watch_for] -lockclient [1076]< - [:held_by] - rwlock [node(97),哈希= 108078135]

我已经提到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

任何建议!

预先感谢!

您可以减少

发生僵局的可能性
  • 使交易较小 - 例如而不是保存1000个节点和关系,而是仅保存100

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

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

  • 捕获例外,然后重新运行交易(本质上是重试)

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

最新更新