为了在一个点上处理重复项,我想在唯一可能的入口点进行:API。
定义:重复
副本是已存在于数据库中的实体,因此 新的POST请求是具有完全相同数据的同一实体,或者是 具有更新数据的同一实体。
API设计旨在处理新的http2协议。
批量进口商已经写好了。该程序从给定的源获取数据,将数据转换为我们的特定格式,并发出POST请求以保存它。此导入程序旨在并行处理每个实体。
API已经有一个复制处理程序,当数据库中已存在给定实体时,它可以很好地工作。当批量导入器同时为同一实体发出多个POST请求时,问题就出现了,并且该实体在数据库中尚不存在。
....POST/1 .databaseCheck.......DataBaseResult=false..........DatabaseWrite
......POST/2 .databaseCheck.......DataBaseResult=false..........DatabaseWrite
........POST/3 .databaseCheck.......DataBaseResult=false..........DatabaseWrite
.....................POST/N .databaseCheck.......DataBaseResult=false..........DatabaseWrite
这种情况会多次生成同一个实体,因为当其余的POST请求到达时,数据库检查尚未完成。 只有当POST请求的数量足够大时,第一个写操作才会完成,第N个请求的databaseCheck将返回true。
处理此问题的正确解决方案是什么? 如果我没有错,我正在寻找的是交易名称,而且我不知道这是否是数据库默认提供的内容,或者是否是我的内容必须实施。
我已经考虑过的解决方案:
1。限制请求,每次只限一次。
这是最简单的解决方案,但是如果在批量导入程序发出多个请求时API仍然被阻止,那么前端客户端将变得非常慢,并且它意味着快速和多人游戏。事实上,这不是一个解决方案。
2。每个实体的特殊批量API端点。
如果应用程序需要发出批量请求,那么只需要一个巨大的POST请求,并将所有数据作为正文请求。 这个解决方案不会阻止API,并且可以很好地处理重复项,但我不喜欢的是我会反对http2协议,其中需要许多小的请求。
问题仍然存在,如果他们没有注意到有可用的批量端点,其他未来的客户可能会遇到此问题。但也许这不是问题。
第3。尝试使用可能的MongoDB事务实现
我已经对此有所了解,但我不知道是否可以使用MongoDB和Mongoose工具来解决这个问题。我做了一些搜索,但我找不到任何东西,因为在尝试插入许多文档之前,我需要为每个文档生成数据,并且每个POST请求中都会包含这些数据。
4。删除MongoDB并使用事务友好数据库。
此时此成本很高,因为整个堆栈已经完成,我们即将启动。我们不怕重构。但我认为这将适用第三种解决方案的考虑因素。
5。自己的API级别的交易实施?
我设计了一个可能适用于所有情况的解决方案,并且我称之为池流。
这是设计: 当POST请求到达时,启动固定量毫秒的计时器。这段时间足以捕获多个请求,并且足够小以免引起明显的延迟。
在每个请求块中,处理数据尝试在写入数据库之前合并重复项。因此,如果在块中n个请求已被捕获,则生成n-m(其中m <= n)个唯一候选。散列函数应用于每个候选者,以便将散列结果分配给每个请求 - 响应对。然后对候选数据库的写操作是并行完成的,并且当前的重复处理程序在写入时可以为此工作。
当当前块的写入完成时,响应被发送到块的每个请求 - 响应对,然后处理下一个块。当一个块在队列中等待写操作时,可以做独特的候选进程,以加速整个过程。
你怎么看? 谢谢。