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 方法 是直接批量插入

MongoDB 默认写入关注保存数据丢失问题与源码简单分析的更多相关文章

  1. 惊人!Spring5 AOP 默认使用Cglib ?从现象到源码深度分析

    Spring5 AOP 默认使用 Cglib 了?我第一次听到这个说法是在一个微信群里: 真的假的?查阅文档 刚看到这个说法的时候,我是保持怀疑态度的. 大家都知道 Spring5 之前的版本 AOP ...

  2. MongoDB源码分析——mongod程序源码入口分析

    Edit 说明:第一次写笔记,之前都是看别人写的,觉得很简单,开始写了之后才发现真的很难,不知道该怎么分析,这篇文章也参考了很多前辈对MongoDB源码的分析,也有一些自己的理解,后续将会继续分析其他 ...

  3. Quartz源码——JobStore保存JonDetail和Trigger源码分析(一)

    我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析方式! {0} :表的前缀 ,如表qrtz_trigger ,{0}== qrtz_ {1}:quartz ...

  4. 在view source页面保存下来的网页源码和保存网页得到的源码不同

    前言 以前抓网页都是直接requests+bs4直接刚的,今天想拿一下拉钩的数据,就继续按照以下步骤来了: 先找个想爬的网页,然后写解析功能 批量爬,然后解析 入库 探究 结果发现行不通了,用bs4去 ...

  5. Hbase写入hdfs源码分析

    版权声明:本文由熊训德原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/258 来源:腾云阁 https://www.qclo ...

  6. Android源码分析(九)-----如何修改Android系统默认时间

    一 : 修改Android系统默认时间 源码路径:frameworks/base/services/java/com/android/server/SystemServer.java 主要变量EARL ...

  7. C#中创建、打开、读取、写入、保存Excel的一般性代码

    ---转载:http://hi.baidu.com/zhaocbo/item/e840bcf941932d15fe358228 1. Excel对象微软的Excel对象模型包括了128个不同的对象,从 ...

  8. python中 对文件的读写操作 以及如何边写入 边保存flush()

    转自:https://blog.csdn.net/t8116189520/article/details/78854708 首先 python中打开文件大致常用的几类如下: 1.写入文件write # ...

  9. Mongodb默认开启与关闭

    默认启动:   $ ./mongodb   默认数据保存路径:/data/db/ 默认端口:27017   修改默认路径:   --dbpath $ ./mongdb --dbpath /mongod ...

随机推荐

  1. ELK基础学习

    第壹部分:Elasticsearch 一 .Elasticsearch增删改查1.数据写入:HTTP method:POSTURL:http://127.0.0.1:9200/index-docs-n ...

  2. Unity3D笔记十一 定制导航菜单栏

    一.定制导航栏 Unity导航菜单栏位于游戏引擎界面的顶部,其中有很多选项且含义各不相同.Unity为开发者提供了导航菜单栏的程序接口,使用代码可以动态添加菜单栏中的选项以及子项 using Unit ...

  3. SQL中distinct的用法(转载)

    1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值.关键词 ...

  4. 170804、使用Joda-Time优雅的处理日期时间

    简介 在Java中处理日期和时间是很常见的需求,基础的工具类就是我们熟悉的Date和Calendar,然而这些工具类的api使用并不是很方便和强大,于是就诞生了Joda-Time这个专门处理日期时间的 ...

  5. python装饰器的应用案例

    目录 一.过程编程 二.面向装饰器和函数的编程 三.二的加强版 一.过程编程 (一)需求:打印菱形 1.空格.*号组成的菱形 2.输入菱形上半部分的行数即可打印 3.支持循环输入 (二)代码 from ...

  6. 如何在linux下安装jdk并运行java程序

    一.进入root 大家可以看到我这里用的是CentOS 6.5 系统 二.测试网络与YUM是否可用 1.测试网络 ping www.baidu.com,如下图就是通了 参考: 一.JDK安装1.lin ...

  7. centos linux系统日常管理复习 CPU物理数逻辑核数,iftop ,iotop ,sar ,ps,netstat ,一网卡多IP,mii-tool 连接,ethtool速率,一个网卡配置多个IP,mii-tool 连接,ethtool速率 ,crontab备份, 第十八节课

    centos linux系统日常管理复习 物理CPU和每颗CPU的逻辑核数,uptime ,w,vmstat,iftop ,iotop ,sar ,ps,netstat ,一个网卡配置多个IP,mii ...

  8. MySQL不能启动 Can't start server : Bind on unix socke

    MySQL服务器突然不能启动,查看最后的启动日志如下: 080825 09:38:04 mysqld started080825 9:38:04 [ERROR] Can't start server ...

  9. Flask系列(九)flask-script组件

    Flask Script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell,设置数据库的脚本,cronjobs,及其他运行在web应用之外的命令行任 ...

  10. 深入理解Nginx

    nginx概述 nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外 ...