RestHeart使用aggregations聚合功能并发冲突问题及解决方案问询
结论先行
事务方案无法解决该并发冲突问题。RestHeart事务仅能保证单次请求内操作的原子性,无法隔离不同并发请求对聚合结果集合的写入操作,多个携带不同avars的请求同时写入同一个固定结果集合时,依然会出现结果覆盖、串数据的问题。
可行解决方案
- 方案1(最优):配置聚合直接返回结果,无需二次查询
你可以在定义聚合pipeline时新增returnResponse: true属性,同时根据数据量配置allowDiskUse: true避免内存超限。配置完成后调用聚合接口会直接返回计算结果,完全不需要二次查询结果集合,从根源上避免并发冲突。 - 方案2:动态指定独立的结果输出集合
定义聚合pipeline时,将$out阶段的目标集合名配置为通过avars传入的动态值,示例pipeline配置片段:
调用接口时在{ "type": "aggregation", "uri": "test-pipeline", "stages": [ // 你的业务筛选、分组阶段 { "$out": "agg_result_${req_id}" } ] }avars中传入全局唯一的req_id(如UUID):
每个请求的结果会写入独立的集合,不会互相覆盖,可定期清理过期的临时结果集合。https://.../_aggrs/test-pipeline?avars={"country":"DE","req_id":"xxxx-xxxx-xxxx-xxxx"} - 方案3:结果集合追加请求标识过滤
若必须使用固定结果集合,可在聚合pipeline中新增$addFields阶段,将请求唯一标识写入所有结果文档:
二次查询结果时增加{ "$addFields": { "req_id": "${req_id}" } }req_id匹配条件,即可过滤出当前请求对应的结果,避免拿到其他用户的数据,该方案需要定期清理结果集合的历史数据避免存储空间浪费。
关于文档未提及该问题的说明
官方默认推荐无动态参数的公共聚合场景,聚合结果写入固定集合可被所有用户复用,不需要区分请求;而带动态avars的多用户自定义查询场景,官方默认引导使用直接返回结果的配置,因此未单独提及并发冲突问题。
内容的提问来源于stack exchange,提问作者Tobag
相关产品推荐
相关产品推荐

