原标题:MySQL PK MongoDB:多文档事务支持,谁更友好?

作者介绍

贺春旸,凡普金科DBA团队负责人,《MySQL管理之道:性能调优、高可用与监控》第一、二版作者,曾任职于中国移动飞信、安卓机锋网。致力于MariaDB、MongoDB等开源技术的研究,主要负责数据库性能调优、监控和架构设计。

MongoDB 4.0已经发布GA版本,并且有许多新功能和改进。在本文中,我们将重点关注主要功能,毫无疑问,这是对多文档ACID事务的支持。我们将围绕隔离级别、可重复读、幻读、事务冲突检测等主要功能,通过实验与MySQL一一做对比。

首先会简述介绍下ACID事务隔离级别,然后再步入测试主题正文。

原子性(Atomicity):事务包含的所有操作要么全部成功,要么全部失败,不存在成功一半的概念。典型例子“西方二元对立思想——非此即彼”:在二元逻辑体系中只存在两种逻辑值,就是对和错,或正和负,不存在既对又错或非正非负的其他状态。

一致性(Consistency):一个事务执行之前和执行之后都必须处于一致性状态。典型例子:“金龙,你借我5000元,下个月开支给你。”不论金龙用什么方式给我转账,分几次转,借钱结束后我银行卡里的余额增加5000元,金龙卡里少了5000元,不能突然蹦出来1万来。

隔离性(Isolation):数据库采用锁机制来实现事务的隔离性,当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。典型例子:“你去医院看病,要先到护士那里分诊排号,如果多个患者加塞儿同时进来,大夫就发飙了,出去排队,只能一个一个看”。

持久性(Durability):事务成功提交后,它对数据库所做的修改就永久保存下来,即使数据库崩溃,数据还能恢复到事务成功提交后的状态。典型例子:“你去ATM机取钱,结果ATM机故障了,你取出来了钱,卡里的余额不能没减。”

一、局限性与限制条件

1、多文档事务仅适用于副本集。

注:如果是单机,需切到副本集模式。

2、仅适用于WiredTiger存储引擎。

3、如果你的架构是分片Sharding模式,事务是不支持的。分布式事务计划在4.2版本里支持。

4、事务只支持CRUD操作,DDL、DCL操作不支持。

注:CRUD就是MySQL的DML,意思一样叫法不同而已。

5、事务无法在config、admin和local系统数据库中读取或写入。

6、事务无法在system.*(系统集合)里写入。

7、不能有大事务写入,写入集不能超过16MB(类似MariaDB Galera Cluster写入集wsrep_max_ws_size限制),否则客户端直接报错。

注:如果有大事务,应该考虑将这些大事务拆分成若干块较小的事务。例如将大于2018年的状态值更改为1,应考虑循环1万条一批量更新,这一点跟MySQL玩法一样。

二、我们第一个事务

在开始事务之前,必须创建会话。事务不能在会话外运行。

var session1 = db.getMongo().startSession()

var session2 = db.getMongo().startSession()

Mongo Shell里引入了三个用于创建,提交和终止事务的新命令:

session.startTransaction()

在当前会话中启动事务

session.commitTransaction()

持久保存事务中的操作变更

session.abortTransaction()

终止事务操作所做的变更

1、在test库创建t1表,并且插入4条数据。

演示一

演示二

空闲事务受transactionLifetimeLimitSeconds参数影响,默认60秒。

可通过以下命令查看:

db.adminCommand( { getParameter: 1, transactionLifetimeLimitSeconds: 1 } )

如果你想在线变更,可以通过下面的命令设置:

db.adminCommand( { setParameter: 1, transactionLifetimeLimitSeconds: 30 } )

也可以写死在/etc/mongod.cnf配置文件里永久生效,格式如下:

setParameter = transactionLifetimeLimitSeconds=30

注:空闲事务是指当一个事务长时间未提交,那么这个连接就不能关闭,内存就不释放,并发一大,导致DB连接数增多,就会对性能产生影响。默认是60秒,你可以根据自己的情况设定阈值。超过这个阈值,服务端自动杀死未提交的空闲事务。

三、事务隔离性演示

演示一:事务冲突检测

当两个(或多个)并发事务修改相同的文档时,会发生冲突。即使在尚未提交事务时,MongoDB也可以立即检测到冲突。

这里和MySQL有些区别,MySQL可以通过参数innodb_lock_wait_timeout设置检测到事务冲突后,自动终止回滚的时间,而MongoDB没有提供该参数。

当在执行创建索引时,未加{background:1})后台创建。

此时新事务将无法获取所需的锁,并且在等待参数maxTransactionLockRequestTimeoutMillis后事务终止回滚,默认值是5毫秒。

如果你想在线调整事务等待获取锁的时间,可以通过下面的命令设置:

db.adminCommand( { setParameter: 1, maxTransactionLockRequestTimeoutMillis: 15 } )

也可以写死在/etc/mongod.cnf配置文件里永久生效,格式如下:

setParameter = maxTransactionLockRequestTimeoutMillis=15

演示二:可重复读

Repeatable Read (可重复读)可避免脏读、不可重复读的发生。

不可重复读侧重点在于更新修改的数据,即在同一个事务里,两次查询的数据结果不一致。与脏读的区别是:脏读是一个事务读取了另一个事务未提交的脏数据。

演示三:幻读

在MySQL默认隔离级Repeatable Read下,刚才的操作,在会话二未提交的事务里,会莫名其妙地看到第5条数据,这种现象称为幻读。

幻读和不可重复读很像,但幻读侧重点在于新增和删除,而不可重复读侧重点在于更改,共同之处都是一个事务中两次查询得到的数据结果不一致。

由此,从测试结果得出的结论是:

MongoDB采用的默认隔离级别是Snapshot一致性快照(特别是设置了readConcern=majority情况下,要读某行数据的历史版本时,依赖该隔离级别。)

Snapshot介于Repeatable Read与Serializable之间,既避免了脏读、不可重复读、幻读,又不会因Serializable串行化降低并发性能。

参考文献

https://docs.mongodb.com/manual/core/transactions/

https://www.percona.com/blog/2018/12/04/mongodb-4-0-using-acid-multi-document-transactions/

责任编辑:

mysql mongodb 事务_MySQL PK MongoDB:多文档事务支持,谁更友好?相关推荐

  1. mysql 迭代更新_MySQL、MongoDB、Redis 数据库之间的区别与使用(本章迭代更新)

    MySQL.MongoDB.Redis 数据库之间的区别与使用 MySQL.MongoDB.Redis 数据库之间的区别与使用(本章迭代更新) update:2019年2月20日 15:21:19(本 ...

  2. java mongodb 多文档_如何通过Java在MongoDB中一次性插入多个文档

    我在我的应用程序中使用MongoDB,需要在MongoDB集合中插入多个文档. 我使用的版本是1.6 我在这里看到一个例子 在里面 批量插入多个文档部分 作者通过数组来做这件事. 当我尝试相同,但为什 ...

  3. MongoDB自学笔记9---4.1 插入文档

    第四章 详解增删改查 对于数据库来说,如果我们不是DBA使用的最多的是CRUD,如果我们学好了CRUD,将来我们操作数据库中的数据的时候,将会得心应手.本章将会详细的介绍mongodb中的CRUD操作 ...

  4. java计算机毕业设计Vue和mysql智能图书管理系统MyBatis+系统+LW文档+源码+调试部署

    java计算机毕业设计Vue和mysql智能图书管理系统MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计Vue和mysql智能图书管理系统MyBatis+系统+LW文档+源码+调 ...

  5. 再见丑陋的 SwaggerUI,这款API文档生成神器界面更炫酷,逼格更高!

    欢迎关注方志朋的博客,回复"666"获面试宝典 一般在使用 Spring Boot 开发前后端分离项目的时候,都会用到 Swagger.Swagger 是一个规范和完整的框架,用于 ...

  6. 超给力,抛弃手动维护,一键生成数据库文档、支持多种格式!

    点击关注公众号,实用技术文章及时了解 简介 在企业级开发中.我们经常会有编写数据库表结构文档的时间付出,从业以来,待过几家企业,关于数据库表结构文档状态:要么没有.要么有.但都是手写.后期运维开发,需 ...

  7. 使用PHPWord把html转成word文档并支持下载

    在开发项目中,遇到的需求:把后台录入的数据保存成word文档,以便其他人员使用.于是在调研的时候,从git上找了PHPWord. PHPWord官方文档 PHPWord git地址 一.安装PHPWo ...

  8. 批量将 PDF 转为 Word 文档,支持 Docx、Doc 格式

    概要:PDF 和 Word 这两种格式是非常常见的,并且相互之间也经常需要进行格式转化.Word 转 PDF是非常容易就能做到的,但是 PDF 转 Word 就经常会碰到各种各样的问题,比如格式错乱. ...

  9. mysql mongodb插件_MySQL和MongoDB设计实例对比分析

    下面通过一个设计实例对比一下二者:假设我们正在维护一个手机产品库,里面除了包含手机的名称,品牌等基本信息,还包含了待机时间,外观设计等参数信息,应该如何存取数据呢? 如果使用MySQL的话,应该如何存 ...

最新文章

  1. 为office添加繁简体转换
  2. SAP BPC最佳实践-如何配置和使用BPC的钻取Drill through
  3. CH4402 小Z的袜子(莫队)
  4. Android app native代码性能分析
  5. 趣图:脸部识别最快的实现
  6. mysql bin_超级有用的15个mysqlbinlog命令
  7. 平面设计师必读的十本书
  8. mysqldump 备份命令使用中的一些经验总结
  9. Atitit 搜索蓝牙设备 powershell的实现 java noede.js python 先用脚本语言python nodejs,不好实现。。Java 也不好实现。。 Netcore可以,
  10. oem13c安装参考
  11. 求字符串转化的最小操作次数 DP动态规划
  12. 洛谷 1938 [USACO09NOV]找工就业Job Hunt
  13. excel 画散点图 怎么设置图片的分辨率_最全的Excel图表的基本类型与选择
  14. 网秦安全盾 原理分析
  15. 电话按键单词问题(C/C++)
  16. 移动磁盘数据错误循环冗余检查的文件找回方法
  17. Windows 10出现0xc0000225错误代码如何解决?
  18. 雷军又找到了一个蓝海:90分如何成为天猫双11预售最大黑马
  19. nod-1089-最长回文子串 V2
  20. 群晖经典第三方套件_使用群晖第三方套件进行IPV6的DDNS

热门文章

  1. STL之accumulate
  2. 【转载】Java方向如何准备BAT技术面试答案(汇总版)
  3. IBM “第8格(Debug)”开发者技术沙龙首站招募中,有胆你就来!
  4. C# Excel导入、导出
  5. 七牛解决运营商劫持问题
  6. 如何使用C#进行PPT展示。
  7. unity3d Aniso Level 摄像机近地面清楚,远地面模糊
  8. app-v 4.6 management server部署(一)
  9. [Web 开发] URL 的最大长度
  10. 用计算机进行实时自动采集,计算机的五大主要用途