V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
whahuzhihao
V2EX  ›  Node.js

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

  •  
  •   whahuzhihao · 2016-03-25 15:27:25 +08:00 · 5403 次点击
    这是一个创建于 3166 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    11 条回复    2016-03-26 14:29:19 +08:00
    jukka
        1
    jukka  
       2016-03-25 15:49:13 +08:00   ❤️ 1
    mongo 自己是没有事物的。

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

    不过一般还得考虑处理超时后别的进程接手的情况呢。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6018 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:08 · PVG 11:08 · LAX 19:08 · JFK 22:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.