MySQL-MVCC并发问题详述

Posted 时而宁靜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL-MVCC并发问题详述相关的知识,希望对你有一定的参考价值。

前言 前边有一篇《mysql-各种锁区分与【MVCC】简单说明了一下mvcc,本篇再次展开叙述。 通常为了获得更好的运行性能,各种 数据库 都允许多个事务同时运行,这就是 事务并发处理 。当并发的事务访问或修改数据库中相同的数据时,通常需要采取必要的隔离机制,反之会出现各种并发问题,mvcc就是来解决事务并发处理下的问题的。 一句话总领一下本篇内容: 对于innodb,通过4种隔离级别的MVCC(多版本并发控制),实现事务并发事务处理,解决并发问题(脏读,不可重复读,幻读)。 每种级别解决的问题也不一样,事务等级越严格,并发副作用越低,付出的代价越大
好可能还是不太明白,详细看看下边吧~
一.并发事务处理:
      1.实现方式:a.悲观锁;b.MVCC
      2.优点
      3.缺点
二.事务隔离机制
      1.四种问题(副作用)
      2.四种隔离级别(解决上边问题)
      3.四种问题情境描述
三.相关命令
四.总结

一.并发事务处理 1.实现方式: a.悲观锁 :在读取数据前,对其加锁,阻止其他事务对数据进行修改 b.MVCC(多版本并发控制) : 不加任何锁,通过一定机制生成 一个数据请求时间点的一致性数据快照 (Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取。从用户的角度来看,好像是数据库可以提供同一数据的多个版本,因此,这种技术叫做数据 多版本并发控制 (MultiVersion Concurrency Control,简称MVCC或MCC)。
2.优点 并发事务处理能大大增加数据库资源的 利用率 ,提高数据库系统的 事务吞吐量 ,从而可以 支持更多的用户
3.缺点 但并发事务处理也会带来一些问题,主要包括以下几种情况。(更新丢失,脏读,不可重复读,幻读) “更新丢失” 通常是应该完全避免的。但防止更新丢失,并不能单靠数据库事务控制器来解决,需要应用程序对要更新的数据加必要的锁来解决,因此,防止更新丢失应该是应用的责任。 “脏读”、“不可重复读”和“幻读” ,其实都是数据库读一致性问题,必须由数据库提供一定的 事务隔离机制 来解决。
二.事务隔离机制 有四种事务隔离机制,越高的机制可以处理更多的副作用。
1.四种问题(副作用): a.更新丢失 b.脏读 c.不可重复读 d.幻读
2.四种隔离级别(解决上边问题): 1).未 提 交 读:解决-a【最基本】 2).已 提 交 读:解决-a,b 3).可 重 复 读:解决-a,b,c【默认的级别】 4).可 序列化读:解决-a,b,c,d
3.四种问题情境描述: a.更新丢失: Lost Update 两个事务同时对一字段处理,出现其中一个丢失现象 当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题-- 最后的更新覆盖了由其他事务所做的更新
num=100
a update set num+=1 num=101
b update set num+=2 num=102
a先提交 b再提交,a的更新丢失
b.脏读: Drity Read 一个事务正在对一条记录做修改, 在这个事务完成并提交前,这条记录的数据就生效了处于不一致状态 ;这时,另一个事务也来读取同一条记录,如果不加控制, 第二个事务 读取了这些“脏”数据 ,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做"脏读"。
a begin transaction
a insert 事务未提交,
b select (可以看到a的insert), 
a rollback
b select (看不到a的insert)
从头到尾b蒙圈儿了,他就read了两次,结果却不同,此为脏读。
c.不可重复读: Non-repeatable Read 一个事务在读取某些数据后的某个时间,再次读取以前读过的数据, 却发现其读出的数据已经发生了改变( update )、或某些记录已经被删除( delete )了 !这种现象就叫做“不可重复读”。(若是发生了insert,那么这种现象就叫幻读了,如下)
a begin transaction
a select (第一次查询的结果)
b begin transaction
b update|delete
b commit
a select (第二次查询的结果,与第一次不相同,不重复,简称不可重复读)
a commit 
a在一个事物里读两次数据不同,造成a里的其他事物操作产生偏差,(能控制b编辑完a在 整体操作就好了)
d.幻读: Phantom Read 指的是插入新行,update|delete不归为幻读
一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入(insert)了满足其查询条件的新数据,这种现象就称为“幻读”。
a begin transaction
a select where ID>100 ,(假如只有101一条数据)
b insert ID=102,(这里是insert表示幻读,要是为update,就成不可重复读了)
b commit 
a select where ID>100 (有101,102两条数据)(b no commit能读出来叫脏读;b commit 叫不可重复读)
a begin transaction
a查询了两次,返回的数据行竟然不相等

三.相关命令
1.查看当前会话隔离级别
select @@tx_isolation;
2.查看系统当前隔离级别
select @@global.tx_isolation;
3.设置当前会话隔离级别
set session transaction isolatin level repeatable read;
4.设置系统当前隔离级别
set global transaction isolation level repeatable read;
5.命令行,开始事务时
set autocommit=off 或者 start transaction


四.总结
数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大。 所以不是越严格越好的,许多应用场景对不可重读和幻读并不敏感,可能更关心数据库的并发访问能力。 根据自己的业务逻辑要求来平衡“隔离”和“并发”矛盾。
参考书籍:《深入浅出MySQL》 本文地址:http://blog.csdn.net/ty_hf/article/details/77624098


以上是关于MySQL-MVCC并发问题详述的主要内容,如果未能解决你的问题,请参考以下文章

MySQL-MVCC多版本控制及事务的隔离性

详述Linux系统中配置Nginx网页优化

linux多线程概念详述

MySQL事务详述

MySQL事务详述

MySQL事务详述