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实战指南》(图书)

△推荐订阅学习

标签智能推荐:

开源数据库

一、关系型数据库MariaDBPostgreSQL二、noSQL的key-value数据库Redis三、noSQL的key-value数据库的文档型数据库MongoDB

UK Day15 - MongoDB、Mongod、Mongo区别

MongoDB:NoSQL中的一种数据库。Mongod:启动MongoDB进程(并在后台运行)。Mongod是处理MongoDB系统的主要进程。它处理数据请求,管理数据存储,和执行后台管理操作。Mongo:Mongod启动MongoDB进程后,(Mongo)对MongoDB进行连接数据库操作。是一个命令行工具。

客户端远程连接mongodb

今天做的是客户端远程连接mongodb数据库:用的是nosql,navicat也可以下面介绍nosql的安装步骤和连接mongodb数据库的连接步骤(用的是网上的教程):官网下载链接:https://nosqlbooster.com/downloads下载后直接打开:&nbsp;输入验证用户名和密码,以及数据库(随便填已有的数据库名称):&nbsp;连接成功:&nbsp;这样nosql就安装好了,

MongoDB数据库基础

1、非关系型数据库基础理论2、NoSQL查询相关

3-11 说一下mysql和mongodb的区别?

模型mongodb-非关系型;mysql-关系型2、存储方式mongodb-以类JSON的文档的格式存储;mysql-不同引擎有不同的存储方式;3、查询语句mongodb-MongoDB查询方式(类似JavaScript的函数);mysql-SQL语句;4、数据处理方式mongodb-基于内存,将热数据存放在物理内存中,从而达到高速读写;mysql-不同引擎有自己的特点;5、成熟度mongodb-

Mysql vs NoSql vs NewSql

,传统关系型数据库,例如MySQLnoSQL,例如MongoDB,CassandranewSQL,例如Aurora,HyperScaleSql传统关系型数据库的索引一般为B+树,读取数据速度很快,但对比NoSql写入速度比较慢.Sql优势在于支持事务,隔离级别,锁等但是随着数据量的越来越大,sql面临许多效率瓶颈,比如过于强大的sql语句功能效率过慢.数据量大的时候需要分库分表,但是分库分表又很难

NoSQL

NoSQL的四大分类:kv键值对:新浪:redis美团:redis+Tair阿里、百度:Redis+memecache文档型数据库(Bson和json一样):MongoDBMongoDB是一个基于分布式存储的数据库,C++编写,主要用来处理大文档MongoDB是一个介于关系型和非关系型中间的产品!MongoDB是非关系型数据库中功能最丰富,最像关系型数据库的。ConthDB列存储数据库:HBase

mysql 创建函数失败解决办法,版本 8.0.26

报错信息:[Err]1418-ThisfunctionhasnoneofDETERMINISTIC,NOSQL,orREADSSQLDATAinitsdeclarationandbinaryloggingisenabled(you*might*wanttousethelesssafelog_bin_trust_function_creatorsvariable)解决方法:setgloballog_

NoSQL注入

NoSQL概念NoSQL,指的是非关系型的数据库。NoSQL有时也称作NotOnlySQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。MongoDBMongoDB属于NoSQL数据库的一种,是由C++语言编写的一个基于分

新框架学习(⊙﹏⊙)

(⊙﹏⊙)体系(架构-思想)--算法(源码-框架)&nbsp;--api(开发-实现)Springboot、Spring&nbsp;cloud、Dubbo、Redis、ActiveMQ、Nginx、Mycat、Spring、MongoDB、ZeroMQ、Git、Nosql、Jvm、Mecached、Netty、Nio、Mina、性能调优、高并发、tomcat负载均衡、大型电商项目实战、高可用、高可