Возможный тупик в JanusGraph при переборе вершин - PullRequest
0 голосов
/ 10 февраля 2020

Я пытаюсь сохранить вершину, представляющую каталог в дереве каталогов в соответствии с этим шаблоном (старый трюк слияния). Свойства WORK_ENVIRONMENT_ID и PATH объединяются в уникальный индекс.

Если вершина не существует, она также подключается к данному environmentVertex через Edge с пометкой CONTAINS. Тем не менее свойство вершины DISCOVERED_AT обновляется.

Упрощенный запрос:

            final String addedVertexStep = "addedVertex";

            Vertex fileVertex = (Vertex) graph.traversal().V()
                /* ... querying for unique properties */
                .fold()
                .coalesce(__.unfold(),
                        __.addV(VertexLabels.FILE)
                                /* setting unique properties */
                                .as(addedVertexStep)
                                .V(environmentVertex.id())
                                .addE(EdgeLabels.CONTAINS)
                                .to(addedVertexStep)
                                .property(PropertyKeys.WORK_ENVIRONMENT_ID, workEnvironmentId.asUUID())
                                .select(addedVertexStep)
                )
                /* updating properties */
                .next();

Полный запрос:

            final String addedVertexStep = "addedVertex";

            Vertex fileVertex = (Vertex) graph.traversal().V()
                .hasLabel(VertexLabels.FILE)
                .has(PropertyKeys.WORK_ENVIRONMENT_ID, workEnvironmentId.asUUID())
                .has(PropertyKeys.PATH, fileMetaInformation.fullPath())
                .fold()
                .coalesce(__.unfold(),
                        __.addV(VertexLabels.FILE)
                                .property(PropertyKeys.PATH, fileMetaInformation.fullPath())
                                .property(PropertyKeys.NAME, fileMetaInformation.simpleName())
                                .property(PropertyKeys.WORK_ENVIRONMENT_ID, workEnvironmentId.asUUID())
                                .property(PropertyKeys.PARENT_PATH, fileMetaInformation.directory().path())
                                .property(PropertyKeys.ID, fileMetaInformation.getId().asUUID())
                                .as(addedVertexStep)
                                .V(environmentVertex.id())
                                .addE(EdgeLabels.CONTAINS)
                                .to(addedVertexStep)
                                .property(PropertyKeys.WORK_ENVIRONMENT_ID, workEnvironmentId.asUUID())
                                .select(addedVertexStep)
                )
                .property(PropertyKeys.DISCOVERED_AT, new Date())
                .next();

Это выполняется сотни раз за все oop в пуле кэшированных потоков, но с использованием той же многопоточной транзакции:

final Graph threadedGraph = graph.tx().createThreadedTx();

Что-то не так с дизайном запроса или способом его выполнения, который вызывает взаимоблокировку? Могу ли я изменить его, чтобы предотвратить это? Вот исключение, которое я получаю.

org.janusgraph.core.JanusGraphException: Possible dead lock detected. Waited for transaction lock without success
    at org.janusgraph.graphdb.transaction.lock.ReentrantTransactionLock.lock(ReentrantTransactionLock.java:46) ~[janusgraph-core-0.4.0.jar:?]
    at org.janusgraph.graphdb.transaction.lock.CombinerLock.lock(CombinerLock.java:45) ~[janusgraph-core-0.4.0.jar:?]
    at org.janusgraph.graphdb.transaction.lock.CombinerLock.lock(CombinerLock.java:42) ~[janusgraph-core-0.4.0.jar:?]
    at org.janusgraph.graphdb.transaction.StandardJanusGraphTx.addProperty(StandardJanusGraphTx.java:769) ~[janusgraph-core-0.4.0.jar:?]
    at org.janusgraph.graphdb.transaction.StandardJanusGraphTx.addProperty(StandardJanusGraphTx.java:745) ~[janusgraph-core-0.4.0.jar:?]
    at org.janusgraph.graphdb.vertices.AbstractVertex.property(AbstractVertex.java:152) ~[janusgraph-core-0.4.0.jar:?]
    at org.janusgraph.core.JanusGraphVertex.property(JanusGraphVertex.java:72) ~[janusgraph-core-0.4.0.jar:?]
    at org.janusgraph.graphdb.util.ElementHelper.attachProperties(ElementHelper.java:80) ~[janusgraph-core-0.4.0.jar:?]
    at org.janusgraph.graphdb.tinkerpop.JanusGraphBlueprintsTransaction.addVertex(JanusGraphBlueprintsTransaction.java:122) ~[janusgraph-core-0.4.0.jar:?]
    at org.janusgraph.graphdb.tinkerpop.JanusGraphBlueprintsTransaction.addVertex(JanusGraphBlueprintsTransaction.java:44) ~[janusgraph-core-0.4.0.jar:?]
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStep.map(AddVertexStep.java:81) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStep.map(AddVertexStep.java:43) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.MapStep.processNextStart(MapStep.java:37) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.hasNext(AbstractStep.java:143) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.ExpandableStepIterator.next(ExpandableStepIterator.java:50) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep.processNextStart(GraphStep.java:158) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.hasNext(AbstractStep.java:143) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.ExpandableStepIterator.next(ExpandableStepIterator.java:50) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.MapStep.processNextStart(MapStep.java:36) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.hasNext(AbstractStep.java:143) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.ExpandableStepIterator.next(ExpandableStepIterator.java:50) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.MapStep.processNextStart(MapStep.java:36) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectOneStep.processNextStart(SelectOneStep.java:131) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.hasNext(AbstractStep.java:143) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal.hasNext(DefaultTraversal.java:192) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.CoalesceStep.flatMap(CoalesceStep.java:58) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.FlatMapStep.processNextStart(FlatMapStep.java:49) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.hasNext(AbstractStep.java:143) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.ExpandableStepIterator.next(ExpandableStepIterator.java:50) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SideEffectStep.processNextStart(SideEffectStep.java:38) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.next(AbstractStep.java:128) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.next(AbstractStep.java:38) ~[gremlin-core-3.4.1.jar:3.4.1]
    at org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal.next(DefaultTraversal.java:200) ~[gremlin-core-3.4.1.jar:3.4.1]

1 Ответ

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

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

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

...