前面我们学习了在MongoDB中如何使用索引来提高查询效率,本篇我们开始进入事务管理部分,首先我们来看看写操作事务。

1 writeConcern详解

通过前面的介绍,我们了解了如何搭建一个MongoDB的复制集实现高可用。要实现高可用,就需要在复制集上有冗余。

那么,对数据的写操作,是需要保证数据成功的在从节点上冗余才能算是高可用的。因此,MongoDB提供了一个writeConcern的参数,它决定了一个数据的写操作要落到多少个节点才算成功。

writeConcern的取值:

(1)0:发起写操作,并不关心是否成功;(实际中不建议使用此方式,无法保证数据的复制是否成功)

(2)1~集群最大节点个数:写操作需要被复制到指定节点个数才算成功;(举例:集群共5个节点,那么此方式需要5个节点都复制成功才算成功。实际中也不建议此方式,延时较长,体验较差)

(3)majority:写操作需要被复制到大多数节点上才算成功;(举例:集群中共5个节点,那么此方式需要5/2=3个节点都复制成功就算成功。实际中建议采用此方式,属于折中考虑的方案)

对于(2)和(3)两种方式,发起写操作的程序将会被阻塞到写操作达到指定的节点个数为止。

综述,从上面的介绍我们可以知道,在实际应用中,建议配置writeConcern为majority,它兼顾了响应时间(性能)和数据冗余(安全),这也是我在团队项目中为MongoDB Driver基础组件设置的默认选项。

2 writeConcern应用

Mongo Shell实验

首先,确保你已经搭建好了一个MongoDB的复制集(replica set),参考《MongoDB入门实战教程(2)》。这里我们有3个节点的复制集,一个primary节点 和 2个secondary节点。

其次,为了模拟网络延迟等待的效果,我们首先在primary节点上通过mongo shell为一个secondary节点设置slaveDelay参数为10s,代表这个secondary节点要等待10s才会被同步数据。

// 拿到复制集的配置
rs0:PRIMARY> conf = rs.conf()
// 查看当前所有members
rs0:PRIMARY> conf.members
// 为第2个secondary节点设置slaveDelay=10s
rs0:PRIMARY> conf.members[2].slaveDelay = 10
// 不让第2个secondary节点参与选举
rs0:PRIMARY> conf.members[2].priority = 0

设置好之后,我们再来试一试带writeConcern参数的insert操作。这里我们先来一个writeConcern=3,即所有3个节点都写成功了才算写入成功,预期结果是等待10s才能成功。

rs0:PRIMARY> db.testDB.insert({count:100}, {writeConcern:{w:3}})

实际结果:等待第2个secondary节点的延迟10s之后才会响应写入成功。

针对这种情况,我们也可以设置一个最大等待时间,超出了就立即响应。

例如,下面设置超过3s就立即响应,不管是否已同步到所有的3个节点:

rs0:PRIMARY> db.testDB.insert({count:100}, {writeConcern:{w:3, wtimeout:3000}})

通过上面的介绍,我们知道将writeConcern设置为majority是比较合适的。

rs0:PRIMARY> db.testDB.insert({count:100}, {writeConcern:{w:"majority"}})

MongoDB .NET Driver实验

在连接字符串级别为所有MongoDB操作设置默认writeConcern级别:

var client = new MongoClient(
"mongodb+srv://<username>:<password>@<cluster-address>/test?w=majority"
);
var database = client.GetDatabase("test");

在Database级别为某个Database设置默认writeConcern为majority:

var mongoClient = new MongoClient("mongodb://mongo-master:27017");
var defaultDbSettings = new MongoDatabaseSettings()
{
WriteConcern = WMajority
};
var mongoDatabase = mongoClient.GetDatabase("products", defaultDbSettings);

在Collection级别为某个Collection设置默认writeConcer为majority:

var defaultCollectionSettings = new MongoCollectionSettings()
{
WriteConcern = WMajority
};
var collection = mongoDatabase.GetCollection<SKU>("sku", defaultCollectionSettings);

在操作语句级别为某个操作设置writeConcern为majority:

var contact = new Contact();
_contacts.WithWriteConcern(WriteConcern.WMajority).InsertOne(contact);

3 总结

本文简单介绍了MongoDB的写操作事务,它有一个重要的参数writeConcern,了解它的选项并在实际项目中应用对于实现数据的高可用至关重要。

下一篇,我们会学习MongoDB的读操作事务,掌握readPreference 和 readConcern 两个重要参数。

参考资料

唐建法,《MongoDB高手课》(极客时间)

郭远威,《MongoDB实战指南》(图书)

△推荐订阅学习

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

MongoDB入门实战教程(10)的更多相关文章

  1. Spark入门实战系列--10.分布式内存文件系统Tachyon介绍及安装部署

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Tachyon介绍 1.1 Tachyon简介 随着实时计算的需求日益增多,分布式内存计算 ...

  2. Kafka入门实战教程(7):Kafka Streams

    1 关于流处理 流处理平台(Streaming Systems)是处理无限数据集(Unbounded Dataset)的数据处理引擎,而流处理是与批处理(Batch Processing)相对应的.所 ...

  3. duilib教程之duilib入门简明教程10.界面设计器 DuiDesigner

    上一个教程讲解了怎么布局最大化.最小化.关闭按钮,但是如果手动去计算这三个按钮的位置和大小的话,非常的不直观,也很不方便.    所以这一章准备介绍duilib的UI设计器,由于这个设计器很不完善,也 ...

  4. ZooKeeper入门实战教程(一)-介绍与核心概念

    1.ZooKeeper介绍与核心概念1.1 简介ZooKeeper最为主要的使用场景,是作为分布式系统的分布式协同服务.在学习zookeeper之前,先要对分布式系统的概念有所了解,否则你将完全不知道 ...

  5. MVC5 + EF6 入门完整教程二

    从前端的UI开始 MVC分离的比较好,开发顺序没有特别要求,先开发哪一部分都可以,这次我们主要讲解前端UI的部分. ASP.NET MVC抛弃了WebForm的一些特有的习惯,例如服务器端控件,Vie ...

  6. MVC5+EF6 入门完整教程 总目录

    本系列文章会从一个主干开始,逐渐深入,初步规划30篇.初级10篇,中级10篇,综合项目实战10篇 初级10篇 MVC5+EF6 入门完整教程10:多对多关联表更新&使用原生SQL@201505 ...

  7. MVC5+EF6 入门完整教程

    MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用 MVC5+EF6 入门完整教程10:多对多关联表更新&使用原生SQL@20150521 MVC5+EF6 入门完整教程9:多表 ...

  8. MVC5+EF6 入门完整教程13 -- 动态生成多级菜单

    稍微有一定复杂性的系统,多级菜单都是一个必备组件. 本篇专题讲述如何生成动态多级菜单的通用做法. 我们不用任何第三方的组件,完全自己构建灵活通用的多级菜单. 需要达成的效果:容易复用,可以根据mode ...

  9. MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用

    摘要: 第一阶段1~10篇已经覆盖了MVC开发必要的基本知识. 第二阶段11-20篇将会侧重于专题的讲解,一篇文章解决一个实际问题. 根据园友的反馈, 本篇文章将会先对呼声最高的仓储模式进行讲解. 文 ...

  10. MVC5+EF6 入门完整教程12--灵活控制Action权限

    大家久等了. 本篇专题主要讲述MVC中的权限方案. 权限控制是每个系统都必须解决的问题,也是园子里讨论最多的专题之一. 前面的系列文章中我们用到了 SysUser, SysRole, SysUserR ...

随机推荐

  1. 在 ThinkPHP 6 控制器中使用文件锁机制

    创建锁管理类 首先,创建一个锁管理类来处理文件锁: namespace app\common\service; use Exception; class LockManager { private $ ...

  2. Ubuntu24使用Wine运行Windows程序安装微信

    Ubuntu24使用Wine运行Windows程序安装微信 2024.11.8:好消息!微信发布Linux版本了,微信主站Linux版本客户端下载页面:https://linux.weixin.qq. ...

  3. ORA-28001:口令已经失效

    Oracle用户口令默认的有效期导致的一个异常,留爪. Oralce11G下,创建的用户及口令,也就是用户密码默认会有个180天的过期时间, 如果超过180天用户口令未做修改,则该用户口令失效,也就是 ...

  4. Visual Studio 2017 导出 ASP.NET Core 项目模版项目文件为空

    问题重现 VS 2017 针对 ASP.NET Core 导出模版功能有问题 解决办法 visual-studio-2017-templates-and-the-missing-content 目前官 ...

  5. Vue3 中的5种常见的组件传值方式,Vue3事件总线(无需插件)

    Vue3 中常见的组件传值方式: Props:这是 Vue 中最常见的组件传值方式,即在父组件中定义 prop 并将数据传递给子组件. Event Bus:可以通过事件总线在两个组件之间进行通信,即定 ...

  6. idea添加类或方法快捷键的方法

    前言: 使用idea有过一段一段时间了,每次写完方法需要都需要注释,要么手动注释要么用快捷键(/** 回车)默认模板注释,不符合项目规定的注释要求,于是想了想是不是设置自定义的注释模板,上网查了资料整 ...

  7. 浏览器如何确定最终的CSS属性值?解析计算优先级与规则

    前言 上篇文章中有提到CSS值的处理过程,但如果想要确定一个元素的最终样式值可以不需要这么多步.实际上我们写的任何一个标签元素无论写没写样式,它都会有一套完整的样式.理解这一点非常重要️ 比如:一个简 ...

  8. SpringBoot——使用http2

    使用http2 许多浏览器,包括Edge,仅在TLS(即HTTPS)情况下支持HTTP/2.即使服务器端配置为无TLS支持的HTTP/2,浏览器可能仍将回退到HTTP/1.1.所以我们需要有一个证书来 ...

  9. 使用libdivide加速整数除法运算

    在x86和ARM平台上,整数除法是相对较慢的操作.不巧的是除法在日常开发中使用频率并不低,而且还有一些其他常用的运算依赖于除法操作,比如取模.因此频繁的除法操作很容易成为程序的性能瓶颈,尤其是在一些数 ...

  10. codeup之等腰梯形

    Description 请输入高度h,输入一个高为h,上底边长为h 的等腰梯形(例如h=4,图形如下). **** ****** ******** ********** Input 输入第一行表示样例 ...