2017-08-30 76 views
0

我一直在尝试使用带有1个CPU和1GB RAM的SpringDataNeo4j(SDN)同时加载测试。 对于'GET'(读取)请求,可以测试1000个线程,并且加速时间为1秒。 对于'POST'(写入)请求,但只能使用18个线程以1秒的斜升进行测试,超出此线程。我们面临着死锁例外:如何避免同时保存数据的弹簧数据neo4j ogm中的死锁

造成的:org.neo4j.ogm.exception.CypherException:错误执行暗号 “Neo.TransientError.Transaction.DeadlockDetected”;代码:Neo.TransientError.Transaction.DeadlockDetected;描述:LockClient [1081]不能等待资源RWLock [NODE(97),hash = 108078135],因为=> LockClient < - [:HELD_BY] - RWLock [NODE(98),hash = 1267379687] < - [:WAITING_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 

任何建议!

在此先感谢!

+0

什么是您在写测试中使用的Cypher语法? –

+0

我在这方面没有使用密码。我正在使用OGM的'Dao.save(node)'API扩展GraphRepository – SriRamaChandra

回答

4

您可以减少死锁通过

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

  • 使用域的结构,确保你不会同时更新同一节点

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

  • 捕获异常,并重新运行交易(主要是自己做重试)

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

+0

非常感谢!我将开始实施。 – SriRamaChandra

+0

我已经实现了节点保存的自定义重试机制,正如您所建议的那样,我发现了一些改进。总是觉得不一致。僵局仍然会减少请求 – SriRamaChandra