我有一个 Java 应用程序,可以在现有节点之间创建 Neo4j 关系。该应用程序有大约 16 个线程(在 16 个 CPU 核心上),每个线程都使用一些 Cypher,例如:
// smRelRows comes from java, as run() parameter
UNWIND $smRelRows AS relRow\s
MATCH ( gene:Gene { appId: relRow.geneId } ),
( concept:Concept { appId: relRow.conceptId } )
CREATE (gene) - [:hasMotifLink{ graphDistance: relRow.graphDistance }] -> (concept)
应用程序将数千个任务排队执行上述操作,但其并行度仅限于 16 个线程。每个查询在
smRelRows
中接收 2500 个值,并在自己的事务中运行。
问题是一切都完全卡住了,在 Neo4j 服务器中,
SHOW TRANSACTIONS
显示了自应用程序启动以来运行的前 16 个查询。
我怀疑由于关系共享节点的锁定而导致一些死锁,但我不知道我该如何解决问题。过去,我编写过类似的基于多线程
CREATE
的更新,没有出现任何问题。
我添加了
appId
的索引,但没有变化。
每个关系创建都会锁定开始和结束节点,因此当任何关系开始或结束节点与正在创建的另一个关系重叠时,您确实会遇到死锁。
我可以看到三个增加复杂性的选项:
UNWIND
和CALL {} IN TRANSACTIONS
可能有帮助)