内容简介:MongoDB 4.0已经发布GA版本,并且有许多新功能和改进。在本文中,我们将重点关注主要功能,毫无疑问,这是对多文档ACID事务的支持。我们将围绕隔离级别、可重复读、幻读、事务冲突检测等主要功能,通过实验与MySQL一一做对比。
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/
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- MongoDB 4.0 正式发布,支持多文档事务
- MongoDB 4.0 首个 RC 版发布,支持多文档事务
- Java事务解析(事务的基本操作+隔离的等级+事务的四大特性+事务的概念)
- 在云中管理事务,第 1 部分: 事务基础和分布式事务
- Spring事务专题(三)事务的基本概念,Mysql事务处理原理
- 嵌套事务、挂起事务,Spring 是怎样给事务又实现传播特性的?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Uberland
Alex Rosenblat / University of California Press / 2018-11-19 / GBP 21.00
Silicon Valley technology is transforming the way we work, and Uber is leading the charge. An American startup that promised to deliver entrepreneurship for the masses through its technology, Uber ins......一起来看看 《Uberland》 这本书的介绍吧!