Neo4J генерирует исключения ForsetiClient для команд, запускаемых в одной транзакции - PullRequest
0 голосов
/ 21 февраля 2020

У меня странная проблема, возникающая в случайные моменты времени для следующих 2 запросов.

MATCH (n:TempLagNode {lag_sys_id: "00:05:9A:30:A0:22"})-[:HAS_TEMP_L2_LAG_INTF ]->(lag:TempL2LagInterface {oper_key: 222})
  -[:HAS_TEMP_L2_LAG_MBR_INTF ]->(member:TempL2LagMemberInterface {oper_port: 1})
DETACH DELETE member

MATCH (n:TempLagNode)-[:HAS_TEMP_L2_LAG_INTF]->(lag:TempL2LagInterface)
WHERE size((lag)-->())=0 AND size((lag)<--())<=2
DETACH DELETE lag

Обе команды выполняются в одной транзакции. Но многократное выполнение вышеупомянутой последовательности приводит к следующему исключению (оно проходит в основном, но иногда терпит неудачу):

java.lang.RuntimeException: org.neo4j.driver.v1.exceptions.TransientException: ForsetiClient[4] can't acquire ExclusiveLock{owner=ForsetiClient[1]} on NODE(205), because holders of that lock are waiting for ForsetiClient[4]. 410  Wait list:ExclusiveLock[411 Client[1] waits for [4]]

Может кто-то прокомментировать, что вызвало выше?

Ответы [ 2 ]

1 голос
/ 22 февраля 2020

Найдена причина root. Когда 2 разных потока пытаются выполнить один и тот же запрос Neo4J (следовательно, разные TX), видны вышеуказанные взаимоблокировки. Исправление их для правильной блокировки между потоками исправило проблему.

0 голосов
/ 21 февраля 2020

См. в этой статье для иллюстрации ситуации взаимоблокировки, которая может вызвать эту ошибку.

Когда вы DETACH DELETE узел, это вызывает попытку удалить этот узел и все его отношения, что вызывает попытку наложения блокировки записи на каждый из них. Кроме того, попытка удаления отношения приводит к попытке установить блокировку записи на каждом из его конечных узлов.

Вот одна последовательность событий, которая может вызвать взаимоблокировку с двумя запросами:

  1. Транзакция 1 начинает выполнение DETACH DELETE member. Это начинается с установки блокировки записи на узле member.
  2. Транзакция 2 начинает выполнение DETACH DELETE lag. Это начинается с установки Write-Lock на lag узле.
  3. Транзакция 1 начинает удаление связей узла member, что, в свою очередь, вызывает попытку Write-Lock того же самого lag узел, для которого транзакция 2 уже имеет блокировку.
  4. транзакция 2 начинает удаление связей узла lag, что, в свою очередь, вызывает попытку записи-блокировки того же узла member, что и транзакция 1 блокировка уже включена.

В результате возникла тупиковая ситуация.

Как указано в вышеприведенной статье, вы можете повторять запросы, которые испытывают такие типы TransientException с, поскольку маловероятно, что при повторной попытке также возникнет тупиковая ситуация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...