我有两个集合,一个(A)包含要处理的项目(相对较小),一个(B)包含已经处理的项目(相当大,有额外的结果字段).
项目从A读取,得到处理并保存()'d到B,然后从A中删除()'d .
理由是指数可以在这些指数之间有所不同,并且"传入"集合可以通过这种方式保持非常小和快.
我遇到了两个问题:
如果remove()或save()超时或者在加载下失败,我会完全丢失该项,或者处理它两次
如果两者都失败了,那么副作用就会发生,但是没有记录
我可以回避使用findAndModify锁的双失败案例(否则不需要,我们有一个进程级锁)但是我们有过时的锁问题,部分失败仍然可能发生.据我所知,没有办法原子地删除+保存到不同的集合(可能是设计?)
这种情况有最佳实践吗?
据我所知,没有办法原子地删除+保存到不同的集合(可能是设计?)
是的,这是设计的.MongoDB显式不提供连接或事务.删除+保存是一种交易形式.
这种情况有最佳实践吗?
你真的有两个低复杂度的选项,都涉及到findAndModify
.
选项#1:单个集合
根据您的描述,您基本上构建了一个具有一些额外功能的队列.如果您利用单个集合,则用于findAndModify
在处理时更新每个项目的状态.
不幸的是,这意味着你将失去这一点:......"传入"集合可以通过这种方式保持非常小和快.
选项#2:两个集合
另一种选择基本上是两阶段提交,利用findAndModify
.
在这里查看文档.
在A中处理项目后,您可以设置一个字段以标记它以进行删除.然后,您该项目全部复制到乙.复制到B后,您可以从A中删除该项目.