首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在亚马逊海王星中使用gremlin javascript语言变体的ConcurrentModificationException

在亚马逊海王星中使用gremlin javascript语言变体的ConcurrentModificationException
EN

Stack Overflow用户
提问于 2021-11-11 17:54:27
回答 1查看 90关注 0票数 0

我正在尝试使用promise.all()检查并插入1000个顶点。代码如下:

代码语言:javascript
复制
public async createManyByKey(label: string, key: string, properties: object[]): Promise<T[]> {
    const promises = [];
    const allVertices = __.addV(label);
    const propKeys: Array<string> = Object.keys(properties[0]);
     
    for(const propKey of propKeys){
      allVertices.property(propKey, __.select(propKey));
    }

    const chunkedProperties = chunk(properties, 5); // [["demo-1", "demo-2", "demo-3", "demo-4", "demo-5"], [...], ...]
    
    for(const property of chunkedProperties){
        const singleQuery = this.g.withSideEffect('User', property)
       .inject(property)
       .unfold().as('data')
       .coalesce(__.V().hasLabel(label).where(eq('data')).by(key).by(__.select(key)), allVertices).iterate();

       promises.push(singleQuery);
     }

    const result = await Promise.all(promises);

    return result;
  }

这段代码抛出ConcurrentModificationException。需要帮助来修复/改进此问题。

EN

回答 1

Stack Overflow用户

发布于 2021-11-11 20:30:21

我不太确定您正在使用的数据和参数,但我需要对您的查询进行一些修改,使其能够使用我手边的数据集(空中路线),如下所示。我这样做是为了帮助我想清楚你的查询在做什么。我不得不更改第二个by步骤。否则,我不确定这是如何工作的。

代码语言:javascript
复制
gremlin> g.inject(['AUS','ATL','XXX']).unfold().as('d').
......1>   coalesce(__.V().hasLabel('airport').limit(10).
......2>            where(eq('d')).
......3>              by('code').
......4>              by(), 
......5>            constant('X'))  
==>v['3']
==>v['1']
==>X 

虽然这样的查询在隔离状态下运行良好,但一旦您开始运行多个异步promise (包含与查询中相同的变化步骤),可能发生的情况是,一个promise试图访问被另一个promise锁定的图的一部分。即使我认为如果一个promise由于IO等待允许另一个promise运行而导致的执行更多地是“并发”而不是真正的“并行”,如果前一个promise已经在数据库中具有下一个promise也需要的锁,那么下一个promise可能会失败。在您的示例中,由于您有一个引用具有给定标签和属性的所有顶点的coalesce,这可能会导致采用冲突的锁。也许,如果你在每次for循环迭代后执行await,而不是在一个大的Promise.all中完成所有这些工作,效果会更好。

要记住的另一件事是,这个查询无论如何都会有一些开销,因为对于每个for循环迭代,中间遍历V将发生五次(在您的示例中)。这是因为注入数据的unfold取自大小为5的块,因此会产生5个遍历,每个遍历都从查看V开始。

编辑于2021-11-17

正如评论中所讨论的,我怀疑最优的路径实际上是使用多个查询。第一个查询只是对您可能要添加的所有ID执行一个g.V(id1,id2,...)。让它返回找到的ID列表。从要添加的集合中删除这些。接下来,将添加部分拆分成批处理,不使用coalesce,因为您现在知道这些元素并不存在。这很可能是减少锁定和避免CME(异常)的最佳方法。除非其他人也在尝试并行添加它们,否则我想我会采用这种方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69932798

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档