知识库

错误 "DeadlockDetectedException: ForsetiClient[0] can’t acquire ExclusiveLock…​ …​" 解释

在特定情况下,可能会遇到 DeadlockDetectedException,其行为在 https://neo4j.ac.cn/docs/java-reference/current/transaction-management/#transactions-deadlocks 中进行了描述。当遇到 DeadlockDetected 时,一个选项是简单地重试该语句。由于死锁检测错误是安全重试错误,并且预期用户在所有应用程序代码中处理这些错误,因为任何时候都可能存在合法死锁,因此这种行为实际上是出于设计考虑以获得可扩展性。以下描述了一个可以演示/重现死锁的场景。

时间 事务 Cypher 语句

08:00:01

tx1001

开始

08:00:02

tx1001

MATCH (n:Person {name:'Tom Hanks'}) set n.age=59;

08:00:03

tx1002

开始

08:00:04

tx1002

MATCH (n:Movie {title:'Cast Away'}) set n.gross=233630478;

08:00:05

tx1001

MATCH (n:Movie {title:'Cast Away'}) set n.budget=90000000;

08:00:06

tx1002

MATCH (n:Person {name:'Tom Hanks'}) set n.residence=California;

在上述场景中,tx1001 在 08:00:01 启动,然后在 08:00:02 对 'Tom Hanks' 的 Person 节点执行更新,并将年龄定义为 59,从而导致在此节点上放置写锁。
然后,tx1002 在 08:00:03 启动,随后在 08:00:04 对 Cast AwayMovie 节点执行更新,并将总收入定义为 233630478,从而导致在此节点上放置写锁。
tx1001 在 08:00:05 尝试更新 Cast AwayMovie 节点,但由于 08:00:04 的事务在此节点上具有写锁而被阻止。
tx1002 在 08:00:06 尝试更新 Tom HanksPerson 节点,但由于 08:00:02 的事务在此节点上具有写锁而被阻止。

由于最后两个语句相互等待,因此检测到死锁,并且 08:00:06 的事务被中止,并显示以下错误

DeadlockDetectedException: ForsetiClient[0] can't acquire ExclusiveLock{owner=ForsetiClient[1]} on NODE(200153), because holders of that lock are waiting for ForsetiClient[0].
 Wait list:ExclusiveLock[
Client[1] waits for [0]]