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. JDK8-时间格式化类-时区类-工具类--java进阶day07

    1.时间格式化类:DateTimeFormatter 1.创建方式 使用DateTimeFormatter调用ofPattern方法即可 . 2.格式化方法 创建好DateTimeFormatter对 ...

  2. vue3第二次传递数据方法无法获取到最新的值

    使用reactive父组件第二次传递给子组件的数据:方法中可以获取到最新数据 <template> <div> <div> <h1>子组件</h1 ...

  3. Web前端入门第 25 问:CSS 中 11 种颜色写法

    曾经,CSS 颜色的写法很专一,就只有十六进制写法(#ff0000)和关键字写法(red). 现在,它变了,变得花样多了,各种招式眼花缭乱. 以红色(red)为例: 1. 颜色关键字 直接使用预定义的 ...

  4. 使用CAMEL实现RAG过程记录

    本文为学习使用CAMEL实现RAG的学习总结. 参考自官方cookbook,地址:https://docs.camel-ai.org/cookbooks/advanced_features/agent ...

  5. 关于:js使用$.parseJSON字符串转json对象报错Uncaught SyntaxError- Unexpected token o in JSON at position 1

    今天使用js使用$.parseJSON字符串转json对象报错Uncaught SyntaxError- Unexpected token o in JSON at position 1,一直找不到原 ...

  6. doctrine-orm基础(单用doctrine避坑指南)

    附: doctrine基础(一):https://www.jianshu.com/p/3681e1add282 doctrine官网: https://www.doctrine-project.org ...

  7. PHP实现文件上传下载实例详细讲解

    一.上传原理与配置 1.1 原理 将客户端文件上传到服务器端,再将服务器端的文件(临时文件)移动到指定目录即可. 1.2 客户端配置 所需:表单页面(选择上传文件): 具体而言:发送方式为POST,添 ...

  8. 从零到一:利用金仓社区数据,LoRa微调与Spring AI 构建私有化千问模型

    上次我们在Coze平台上成功搭建了一个针对金仓问题的解决助手.这个智能体的核心工作流程相对简单:每次它通过HTTP接口调用插件,在金仓平台内部进行搜索,随后利用大模型的推理能力对查询结果进行分析,从而 ...

  9. 【AI+教学】让课堂实时讲解语音知识库沉淀下来

    今天给大家分享一个教学的 AI 使用场景,主要用来解决课堂老师实时讲解的内容如何让学生快速了解学习. 一.教学场景说明: 课堂上老师上完课后,课堂实时讲解的内容,部分与教材或者课件有偏差(临场发挥), ...

  10. frp增加IP限制

    核心设计理念 传统frp安全方案的不足 静态配置文件管理白名单IP,修改需要重启服务 分布式环境下多节点配置同步困难 缺乏实时阻断恶意IP的能力 Redis作为动态白名单存储的优势 实时生效:IP规则 ...