如何在同时保存数据的同时避免弹簧数据neo4j ogm中的死锁

时间:2017-08-30 18:00:55

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

我一直在尝试使用带有1个CPU和1GB RAM的SpringDataNeo4j(SDN)同时加载测试。 对于'GET'(读取)请求,能够以1秒的上升速度测试1000个线程。 对于'POST'(写入)请求,但是能够仅使用18个线程进行测试,其中斜坡上升为1秒,超出此线程。我们面临DeadLock异常:

  

引起:org.neo4j.ogm.exception.CypherException:执行Cypher“Neo.TransientError.Transaction.DeadlockDetected”时出错;代码:Neo.TransientError.Transaction.DeadlockDetected;说明:LockClient [1081]无法等待资源RWLock [NODE(97),hash = 108078135],因为=> LockClient [1081]< - [:HELD_BY] - RWLock [NODE(98),hash = 1267379687]< - [:WAITING_FOR] - LockClient [1076]< - [:HELD_BY] - RWLock [NODE(97),散列= 108078135]

我已经提到了 https://developers.google.com/cloud-messaging/android/client

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

任何建议!

提前致谢!

1 个答案:

答案 0 :(得分:4)

您可以通过

降低发生死锁的可能性
  • 使交易变小 - 例如而不是保存1000个节点和关系,只保存100

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

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

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

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