MongoDB在4.2版本开始全面支持了多文档事务,这也让MongoDB可以作为OLTP的选项之一,本篇我们就来学习一下MongoDB的多文档事务。

1 ACID支持程度

谈到事务,就不得不提经典的ACID特性,MongoDB对ACID的支持程度到底如何呢?且看下表:

事务属性 支持程度
Atomocity 原子性 单表单文档:1.x 就开始支持
复制集多表多行:4.0 开始支持
分片集多表多行:4.2 开始支持
Consistency 一致性 writeConcern, readConcern
Isolation 隔离性 readConcern
Durability 持久性 Journal and Replication

2 多文档事务使用方法

基本使用方式

MongoDB多文档事务的使用方式与关系型数据库基本类似。

但是需要注意的是:多文档事务只能应用在副本集 或 mongos 节点上。如果你只是一个单点的mongo实例,是无法进行多文档事务实践的。

如何搭建一个mongodb的复制集?参考《MongoDB入门实战教程(2)

在Mongo Shell中的实践

下面演示了如何通过Mongo Shell来进行一个多文档操作的事务提交:

var session = db.getMongo().startSession();
session.startTransaction({readConcern: { level: 'majority' },writeConcern: { w: 'majority' }}); var coll1 = session.getDatabase('students').getCollection('teams');
coll1.update({name: 'yzw-football-team'}, {$set: {members: 20}}); var coll2 = session.getDatabase('students').getCollection('records');
coll1.update({name: 'Edison'}, {$set: {gender: 'Female'}}); // 成功提交事务
session.commitTransaction(); // 失败事务回滚
session.abortTransaction();

在.NET Driver中的实践

using (var clientSession = mongoClient.StartSession())
{
try
{
var contacts = clientSession.Client.GetDatabase("testDB").GetCollection<Contact>("contacts");
contacts.ReplaceOne(contact => contact.Id == "1234455", contact);
var books = clientSession.Client.GetDatabase("testDB").GetCollection<Book>("books");
books.DeleteOne(book => book.Id == "1234455"); clientSession.CommitTransaction();
}
catch (Exception ex)
{
// to do some logging
clientSession.AbortTransaction();
}
}

在Java Driver中的实践

try (ClientSession clientSession = client.startSession()) {
clientSession.startTransaction();
collection.insertOne(clientSession, docOne);
collection.insertOne(clientSession, docTwo);
clientSession.commitTransaction();
}

扩展:事务的隔离级别

关于MongoDB的事务隔离级别,有以下亮点说明:

(1)默认情况下,在MongoDB的事务完成前,事务外的操作对该事务所做的修改是访问不到的

(2)如果我们在开启事务时设置 {readConcern: "snapshot"},则可以达到可重复读(Repeatable Read)的级别,这也是MySQL的默认事务隔离级别。而如果我们设置{readConcern: "majority"},则可以达到读提交(Read Commited)的级别,这是MSSQL的默认事务隔离级别。

3 注意事项

MongoDB可以实现和关系型数据库类似的事务场景,但在应用程序开发的时候必须使用与4.2及以上版本兼容的Driver。

事务默认必须在60s内完成,否则将被取消。当然,我们也可以调整这个默认值,但是建议不要超过60s。

多文档事务中的读操作必须使用主节点读取,这是为了保证事务的数据强一致性。

虽然,MongoDB在4.2版本开始全面支持多文档事务,但是并不代表我们可以毫无节制地使用它。相反,对事务的使用原则应该是:能不用尽量不用

通过合理地设计文档模型,其实可以规避绝大部分使用事务的必要性。

Why?因为 事务 = 锁,节点协调,额外开销,性能影响 ...

4 总结

本文简单介绍了MongoDB多文档事务的使用,它弥补了MongoDB无法实现传统关系型数据库ACID特性的不足。

下一篇,我们会学习MongoDB的分片集原理 及 分片策略。

参考资料

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

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

△推荐订阅学习

作者:周旭龙

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

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

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

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

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

  2. duilib教程之duilib入门简明教程12.简单控件介绍

    前面的教程应该让大家对duilib的整体有所映像了,下面就来介绍下duilib具体控件的使用.    由于官方没有提供默认的控件样式,所以我就尽量使用win7或者XP自带的按钮样式了,虽然界面比较土鳖 ...

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

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

  4. Node+Express+MongoDB+Socket.io搭建实时聊天应用实战教程(一)--MongoDB入门

    前言 本文并不是网上流传的多少天学会MongoDB那种全面的教程,而意在总结这几天使用MongoDB的心得,给出一个完整的Node+Express+MongoDB+Socket.io搭建实时聊天应用实 ...

  5. MongoDB入门必读(概念与实战并重)

    MongoDB入门必读(概念与实战并重) 一.概述 MongoDB是一个基于分布式文件存储的数据库开源项目.由C++语言编写.旨在为WEB应用提供可护展的高性能数据存储解决方案. MongoDB是一个 ...

  6. Node+Express+MongoDB + Socket.io搭建实时聊天应用实战教程(二)--node解析与环境搭建

    前言 本来开始写博客的时候只是想写一下关于MongoDB的使用总结的,后来觉得还不如干脆写一个node项目实战教程实战.写教程一方面在自己写的过程中需要考虑更多的东西,另一方面希望能对node入门者有 ...

  7. mybatis实战教程(mybatis in action),mybatis入门到精通

    转自:http://www.yihaomen.com/article/java/302.htm (读者注:其实这个应该叫做很基础的入门一下下,如果你看过hibernate了那这个就非常的简单) (再加 ...

  8. mybatis实战教程(mybatis in action),mybatis入门到精通(转)

    转自:http://www.yihaomen.com/article/java/302.htm (读者注:其实这个应该叫做很基础的入门一下下,如果你看过Hibernate了那这个就非常的简单) (再加 ...

  9. mongodb入门教程二

    title: mongodb入门教程二 date: 2016-04-07 10:33:02 tags: --- 上一篇文章说了mongodb最基本的东西,这边博文就在深入一点,说一下mongo的一些高 ...

  10. mongodb入门教程

    title: mongodb入门教程 date: 2016-04-06 14:47:18 tags: --- 为什么要认识呢,因为这玩意就一傻逼 借用一下百科的介绍 MongoDB 是一个介于关系数据 ...

随机推荐

  1. Python 潮流周刊#95:像人类一样使用计算机(摘要)

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  2. idea的deployment没有war包

    一.解决方案

  3. 【自用】git提交commit 注释规范

    git初始化 首先下载安装git,配置好公私密钥和github git命令 git init git remote add origin [远程库地址] git pull origin master ...

  4. 什么是 Write-Ahead Logging (WAL) 技术?它的优点是什么?MySQL 中是否用到了 WAL?

    什么是 Write-Ahead Logging (WAL) 技术? Write-Ahead Logging (WAL) 是一种用于数据库系统的日志记录技术,它要求在对数据库进行任何修改之前,所有的修改 ...

  5. 面试官:SpringBoot 工程启动以后,希望将数据库中已有的固定内容提前加载到 Redis 缓存中,应该如何处理

    这个问题说白了就是希望通过预加载数据,达到提升系统性能和响应速度的效果.像目前在很多场景中都有使用: 电商平台的商品分类信息.用户基础资料:避免高并发时数据库被重复查询,降低响应延迟. 系统参数配置( ...

  6. 在Avalonia/C#中使用依赖注入过程记录

    前言 使用依赖注入可以让我们的程序变得更加好维护与测试. 今天分享的是在Avalonia/C#中使用依赖注入. 我准备了一个简单的不使用依赖注入与使用依赖注入的demo. 该demo已上传至GitHu ...

  7. Python3正则表达式(一)

    Python3正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. r ...

  8. 【记录】SMB|Windows下修改SMB端口并挂载

    环境:Window11 使用背景:勒索病毒导致445端口不安全,故而该端口在服务器端被全面禁用了,如需使用SMB服务需要换个SMB服务端口. 方法1:端口转发 win+x点开管理员权限的终端: 输入如 ...

  9. 基于Kubernetes可扩展的Selenium 并行自动化测试部署及搭建(2)——Win10环境下Kubernetes(k8s)部署

    继续上一篇,本篇进行K8S环境部署. K8s部署: 1.  访问k8s-for-docker-desktop 的github地址: https://github.com/AliyunContainer ...

  10. rust引入含有openssl相关包报错(openssl未找到和编译运行报错等相关问题)解决方案

    1. 问题描述 某天在我的rust程序里引入了actix-proxy = "0.2"这个包,我的程序编译通不过了,rust-analyser也罢工了,错误也提示不出来了,查看错误提 ...