zoukankan      html  css  js  c++  java
  • MongoDB 默认写入关注保存数据丢失问题与源码简单分析

    MongoDB 默认写入关注可能保存数据丢失问题分析

    问题描述:

           EDI服务进行优化,将原有MQ发送成功并且DB写入成功,两个条件都达成,响应接收订单数据成功,修改为只有有一个条件成功就响应接收数据成功。只要发送MQ成功,就代表数据已经给下游客单系统,保存DB数据失败可以接受,优先保证数据不阻断。发送MQ失败,保存DB数据成功,代表我们已经接受到订单数据,可以通过容错服务进行后续处理。这样就可以保证MQ与DB只要有任何一个是没问题就不会影响客户订单数据的正常下发。

    近期发生MQ服务端忙碌,拒收生成消息。理论上数据应该已经保存到DB。通过容错服务就可以处理。但是客单系统确实没有收到,并且数据库中也并未查询到。ELK确实记录了客户是已经发送订单下发请求并且我们也返回成功了。

    经过ELK日志记录排查,可以得到MQ发送失败,DB保存没有抛异常,应该算DB已经保存成功。但是实际却没成功。

    经过一番排查,应该是默认的保存数据的写入关注策略问题。

    默认写入关注设置为:WriteConcern.NORMAL

    WriteConcern概述:

    WriteConcern.NONE:               没有异常抛出

    WriteConcern.NORMAL:           仅抛出网络错误异常,没有服务器错误异常

    WriteConcern.SAFE:                 抛出网络错误异常、服务器错误异常;并等待服务器完成写操作。

    WriteConcern.MAJORITY:         抛出网络错误异常、服务器错误异常;并等待一个主服务器完成写操作。

    WriteConcern.FSYNC_SAFE:      抛出网络错误异常、服务器错误异常;写操作等待服务器将数据刷新到磁盘。

    WriteConcern.JOURNAL_SAFE:  抛出网络错误异常、服务器错误异常;写操作等待服务器提交到磁盘的日志文件。

    WriteConcern.REPLICAS_SAFE:  抛出网络错误异常、服务器错误异常;等待至少2台服务器完成写操作

    Spring MongoDB 设置

           <mongo:client-options write-concern="SAFE " />

    Spring data MongoDB

    @Autowired
    MongoTemplate mongoTemplate;
    mongoTemplate.setWriteConcern(WriteConcern.ACKNOWLEDGED);
    mongoTemplate.save(data,"ediData");

    说明:

    @Deprecated
    public static final WriteConcern SAFE = ACKNOWLEDGED;

    SAFE 已经被弃用,源码可以看到直接设置为了 ACKNOWLEDGED

    关于Spring data jap MongoDB MongoRepository 接口的说明与源码分析:

           MongoRepository提供了简单直接的几个方法,其中就有 save 方法。

    单条保存源码流程。

               

    批量保存

     

    可以看到如果是新增数据(没有设置ID),用save 其实也是走的 insert方法。
     

    Mongodb insert 与 save 的区别说明

      insert:当主键"_id"在集合中存在时,不做任何处理。 抛异常

      save:当主键"_id"在集合中存在时,进行更新。 数据整体都会更新 ,新数据会替换掉原数据 ID 以外的所有数据。如ID 不存在就新增一条数据

           save 方法 需要遍历列表,一个个插入, 而 insert 方法 是直接批量插入  

  • 相关阅读:
    v$session,v$session_wait,v$session_wait_history,v$active_session_history
    ORACLE 12C PDB部分功能测试
    关于A基金和B基金的了解
    insert /*+ APPEND */
    使用ADRCI (ADR Command Interpreter) 工具查看Oracle alert警告日志
    Linux┊详解udev
    Cache Fusion
    ORACLE的临时表
    【转】k8s集群自定义clusterRole样例
    prometheus监控java项目(jvm等):k8s外、k8s内
  • 原文地址:https://www.cnblogs.com/atliwen/p/9885258.html
Copyright © 2011-2022 走看看