[提问] node 里如何避免 mongodb 的脏读?

2016-03-25 15:27:25 +08:00
 whahuzhihao

mongo 的 api 都是回调的方式,我每次从库里查出符合条件的记录,然后在回调函数中将这几条记录 update 掉状态,让他们不会再其他请求中被查找出来,相当于被消费掉了。

虽然还没遇到脏读的情况,但是我心里觉得是有隐患的。因为查找和更新不是一个事务里,而 node 处理事件的方式又是可以并发的,所以我担心并发的情况下,会造成 mongodb 脏读,多次消费同一个记录。

有没有好的解决方法?比如类似于 Critical Section 的方案,让竞争资源的代码不可以同时运行?

5426 次点击
所在节点    Node.js
11 条回复
jukka
2016-03-25 15:49:13 +08:00
mongo 自己是没有事物的。

你要用类似 async 来控制并发,让你这些访问数据库的操作顺序执行。
whahuzhihao
2016-03-25 16:23:09 +08:00
@jukka async 确实可以控制并发,但是我用的 mongojs 的 api 对于库的操作,还是异步的。。
所以即使控制了并发请求,让其串行处理,还是不能解决问题。
lynnworld
2016-03-25 16:26:21 +08:00
用 findAndModify .设个状态字段, undo,doing,done,
tabris17
2016-03-25 16:29:09 +08:00
那只能模拟 MVVC 了
whahuzhihao
2016-03-25 16:41:19 +08:00
@lynnworld 其实我也想用这个 findAndModify ……
但是因为要随机取,所以用的是 aggregate + $sample 管道。貌似 aggregate 里没有同时修改的方法。
incompatible
2016-03-25 16:46:56 +08:00
1. 换 mysql ,用悲观锁
2. 用 CAS 机制自己做乐观锁
fengkuok
2016-03-25 16:48:34 +08:00
@whahuzhihao async 不是解决办法,集群不照样有问题
MiguelValentine
2016-03-25 16:58:04 +08:00
用集群,由 master 做锁调度
BOYPT
2016-03-25 23:09:16 +08:00
@whahuzhihao 不需要同时修改吧, findAndModify 时候如果已经被消费了就不会产生任何效果。
magicdawn
2016-03-26 13:47:53 +08:00
fds
2016-03-26 14:29:19 +08:00
查找到数据后, update 时带上查找条件,比如
collection.update({_id:123,proc:{$exists:false}},{$set:{proc:1}})
然后看返回的 modified 数量是不是 1 ,不是就不要处理。

不过一般还得考虑处理超时后别的进程接手的情况呢。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/266319

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX