MySQL和MongoDB中多文档事务支持扥功能的对比

48次阅读
没有评论

共计 2901 个字符,预计需要花费 8 分钟才能阅读完成。

本篇内容介绍了“MySQL 和 MongoDB 中多文档事务支持扥功能的对比”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让丸趣 TV 小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

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

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

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

一致性(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

演示二:可重复读

MySQL 和 MongoDB 中多文档事务支持扥功能的对比

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

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

演示三:幻读

MySQL 和 MongoDB 中多文档事务支持扥功能的对比

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

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

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

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

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

MySQL 和 MongoDB 中多文档事务支持扥功能的对比

“MySQL 和 MongoDB 中多文档事务支持扥功能的对比”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注丸趣 TV 网站,丸趣 TV 小编将为大家输出更多高质量的实用文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-28发表,共计2901字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)