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》



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值