更新顶点时 JanusGraph 中可能出现死锁
Possible deadlock in JanusGraph when upserting Vertex
我正在尝试根据 (旧的合并技巧)在目录树中插入表示目录的顶点。属性 WORK_ENVIRONMENT_ID
和 PATH
组合在一个唯一索引中。
如果顶点不存在,它也通过标记为 CONTAINS
的 Edge
连接到给定的 environmentVertex
。尽管如此,顶点的 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();
这在缓存线程池中循环执行数百次,但使用相同的线程事务:
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]
事实证明,这不是死锁,而是锁拥塞,因为我在同一个事务中批量加载了数千个具有唯一性约束的顶点。
为了修复它,我为每个顶点(或上面目录示例中的顶点链)打开了一个新事务,并在更新下一个顶点(链)之前提交了事务。
我正在尝试根据 WORK_ENVIRONMENT_ID
和 PATH
组合在一个唯一索引中。
如果顶点不存在,它也通过标记为 CONTAINS
的 Edge
连接到给定的 environmentVertex
。尽管如此,顶点的 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();
这在缓存线程池中循环执行数百次,但使用相同的线程事务:
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]
事实证明,这不是死锁,而是锁拥塞,因为我在同一个事务中批量加载了数千个具有唯一性约束的顶点。
为了修复它,我为每个顶点(或上面目录示例中的顶点链)打开了一个新事务,并在更新下一个顶点(链)之前提交了事务。