zoukankan      html  css  js  c++  java
  • 转载:在恰当的地方使用MongoDB的WriteConcern.SAFE参数

    http://blog.csdn.net/xinghebuluo/article/details/7035123


    分类: mongodb应用2011-12-0215:01 391人阅读 评论(0) 收藏 举报

    首先列一下WriteConcern的几种抛出异常的级别参数:

    • WriteConcern.NONE:没有异常抛出
    • WriteConcern.NORMAL:仅抛出网络错误异常,没有服务器错误异常
    • WriteConcern.SAFE:抛出网络错误异常、服务器错误异常;并等待服务器完成写操作。
    • WriteConcern.MAJORITY: 抛出网络错误异常、服务器错误异常;并等待一个主服务器完成写操作。
    • WriteConcern.FSYNC_SAFE:抛出网络错误异常、服务器错误异常;写操作等待服务器将数据刷新到磁盘。
    • WriteConcern.JOURNAL_SAFE:抛出网络错误异常、服务器错误异常;写操作等待服务器提交到磁盘的日志文件。
    • WriteConcern.REPLICAS_SAFE:抛出网络错误异常、服务器错误异常;等待至少2台服务器完成写操作。

     

    当我们执行如下操作时(将"name"为"lily"的"age"设置为20):

    db.update({"name":"lily"},{"$set":{"age":20}})
    

    默认情况下,该操作会使用WriteConcern.NORMAL(仅在网络错误时抛出异常),等同于:

    db.update({"name":"lily"},{"$set":{"age":20}},WriteConcern.NORMAL)
    

    使用NORMAL模式参数,可以使得写操作效率非常高。但是如果此时服务器出错,也不会返回错误给客户端,而客户端会误认为操作成功。

    因此在很多重要写操作中需要使用WriteConcern.SAFE模式,保证可以感知到这个错误,保证客户端和服务器对一次操作的正确性认知保持一致。

    (根据笔者测试,如果服务器发生掉电情况,客户端依然得不到当时操作的错误返回,需要特别注意)

    另外在很多时候,我们需要确切知道这次写操作是否成功(或者本次更新操作影响了多少个对象),这时候就需要:

    WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
    if(ret.getN()>0) //操作影响的对象个数
        return true;
    else
        return false;
    

    或者:

    WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
    if(ret.getLastError() == null)
        return true;
    else
        return false;
    

    此时,getLastError()会查询上次操作结果是否出现错误。

    更进一步

    然后由于mongodb中使用连接池的原因,getLastError()需要再次从连接池中获取连接,这样效率会慢一些。可以这样做:

    db.requestStart();
    WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
    if(ret.getLastError() == null)
        return true;
    else
        return false;
    db.requestDone();
    

    就可以保证update操作和getLastError()使用同一个连接,并且减少了一次存/取连接的过程。

     

    还有一个方法

    此时也可以使用WriteConcern.SAFE参数:

    WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}}, WriteConcern.SAFE);
    if(ret.getLastError() == null)
        return true;
    else
        return false;
    
    // is equivalent to 
    db.requestStart();
    WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
    if(ret.getLastError() == null)
        return true;
    else
        return false;
    db.requestDone();
    

    这也是我推荐使用的方式,这样即可以高效的得到返回结果,还能感知到服务器错误,一举两得。

  • 相关阅读:
    9.11 eventbus
    9.10,,,实现new instanceof apply call 高阶函数,偏函数,柯里化
    9.9 promise实现 写完了传到gitee上面了,这里这个不完整
    9.5cors配置代码
    9.5 jsonp 实现
    9.5 http tcp https总结
    9.3 es6 class一部分 and es5 class 发布订阅
    8.30 cookie session token jwt
    8.30vue响应式原理
    warning: LF will be replaced by CRLF in renard-wx/project.config.json. The file will have its original line endings in your working directory
  • 原文地址:https://www.cnblogs.com/leeeee/p/7276595.html
Copyright © 2011-2022 走看看