gpt4 book ai didi

java - 如何在并发保存数据时避免spring data neo4j ogm中的死锁

转载 作者:行者123 更新时间:2023-11-29 08:33:27 24 4
gpt4 key购买 nike

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

Caused by: org.neo4j.ogm.exception.CypherException: Error executing Cypher "Neo.TransientError.Transaction.DeadlockDetected"; Code: Neo.TransientError.Transaction.DeadlockDetected; Description: LockClient[1081] can't wait on resource RWLock[NODE(97), hash=108078135] since => LockClient[1081] <-[:HELD_BY]- RWLock[NODE(98), hash=1267379687] <-[:WAITING_FOR]- LockClient[1076] <-[:HELD_BY]- RWLock[NODE(97), hash=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);
    }
    }
  • 使用一些已经实现了重试逻辑的库,比如 spring-retryguava-retrying

关于java - 如何在并发保存数据时避免spring data neo4j ogm中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45966965/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com