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. 面试题-Storm框架

    前言 Storm框架在实际项目中已经平稳运行快一年了,也很好的支撑了海量读写器的数据处理需求,不过和RabbitMQ一样,为了项目进度,实际工作中只能尽快的调研,关注一些关键点,其他的细节就只能放一放 ...

  2. 代码块--java进阶day03

    1.代码块 1.局部代码块 定义在方法中的一对大括号,可以提早释放内存,走完{}里的逻辑后就会被释放,在之后的编程中无法使用 2.构造代码块 位置在类中,方法外的{},在构造方法执行的时候,构造代码块 ...

  3. 【Java】操作数据库

    工具: eclipse MySQL Navicat for MySQL MySQL 连接驱动:mysql-connector-java-5.0.4-bin.jar SQL 代码 CREATE TABL ...

  4. 【C语言】解决初始化数组时报错“undefined reference to `memcpy'”

    [C语言]解决初始化数组时报错"undefined reference to `memcpy'" 零.报错 代码: char start[] = {0xd, 0xa, 0xb3, ...

  5. EntityFrameworkCore 分页问题

    场景重现 使用 EntityFrameworkCore 连接 SQL Server 2008 执行.Skip().Take()分页查询时出现如下异常: SqlException: 'OFFSET' 附 ...

  6. S7.Net与西门子PLC通讯——纯新手必看

     前言 本文档适合从未接触过PLC的.NET开发程序员入门查看.(其实看完了之后,PLC开发也就那样) PLC通讯入门比较难,需要关注的细节比较多.一边学习一边举一反三多思考,一定要自己创建Demo跟 ...

  7. Redis使用IO多路复用进行事件处理机制

    一.epoll多路复用 这里重点要说的就是redis的IO编程模型,首先了解下 为什么要有多路复用呢 ? 案例 引用知乎上一个高赞的回答来解释什么是I/O多路复用.假设你是一个老师,让30个学生解答一 ...

  8. Python3处理文档_word文档(三)_向word文档中添加表格

    利用python-docx自动生成表格 add_table()方法会返回一个Table对象.rows代表行数,cols代表列数:style代表样式,具体可以查看官方文档. 一.创建一个8行5列的表格 ...

  9. AI 辅助开发实战分享:解决Selenium自动化设置Ant时间组件难题

    AI 辅助开发实战分享:解决Selenium自动化设置Ant时间组件难题 在软件开发这一块,自动化那可是提高效率.少出错的关键.不过呢,在实际搞自动化开发的时候,开发者们常常会碰到各种各样的麻烦和障碍 ...

  10. SpringBoot3特性——错误信息Problemdetails

    Spring Framework 6 实现了 HTTP API 规范 RFC 7807 的问题详细信息. 在本文中,我们将学习如何在 SpringBoot 3 REST API(使用 Spring F ...