MySQL事务隔离级别及事务并发问题

  • Post author:
  • Post category:mysql




一、事务基本定义(ACID)


1、原子性(Atomicity)

:事务一旦开始,那么我们只能有两个结果,要么全部执行完成,要么全部都不做,不能停滞在事务中途。如果在执行中出错,必须把事务回滚到事务开始前。


2、一致性(Consistency)

:事务开始前和结束后,数据库的完整性约束没有被破坏 。比如买东西,付款的时候,我扣钱成功了,对方也一定要收到钱,不能出现我扣了钱,对方却没收到。


3、隔离性(Isolation)

:同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。


4、持久性(Durability)

:事务一旦完成,那必须保存到数据库,并且不能回滚。



二、事务的并发问题



首先我们搞懂这几个由于并发访问导致的数据读取问题


1、脏读(读取到了执行中未提交的数据)


事务A读取到了事务B尚未提交的数据,如果事务B回滚了操作,那么事务A就是读到了脏数据。

这种情况主要发生在查询数库时的并发问题


例如:


这个场景就读取到了未提交的脏数据了,产生了脏读

时间轴 查询事务 新增事务
1 开始查询 开始修改
2 查询到数据为100 修改数据为100
3 返回查询数据100 操作发生未知错误事务回滚
4 提交事务 数据回滚成修改前数据


2、不可重复读(事务执行中多次读取,数据内容不一致)


事务A在读取数据时,由于整个事务A操作比较多,事务需要多次读取同一条数据时,间隔需要比较长的时间 。事务A在第一次读取数据,比如读取到年龄为15岁,事务B执行更改操作,将年龄更改为25岁,此时事务A第二次读取到年龄时,发现其年龄是25岁,和之前的数据不一样了,也就是数据不重复了,从而导致了不可重复读。


例如:


这个场景事务A前后两次读取到的数据不一致导致不可重复读

时间轴 事务A 修改事务
1 开始事务
2 第一次查询到A年龄为15
3 开始事务
4 其它操作
5 更改A年龄为25
6 提交事务
7 第二次查询到A年龄为25


3、幻读(事务执行中多次读取,数据总量不一致)


事务A在读取数据时,由于整个事务A操作比较多,事务需要多次统计数据的总量,间隔需要比较长的时间 。第一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,这个时候事务A第二次读取的数据总量和第一次统计的不一样,多了几条数据,成为幻读。


例如:


这个场景事务A前后两次读取到的数据总量不一致导致幻读

时间轴 事务A 批量新增事务
1 开始事务
2 第一次查询,数据总量为100条
3 开始事务
4 其它操作
5 新增100条数据
6 提交事务
7 第二次查询,数据总量为200条

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。



三、MySQL事务隔离级别



上面我们说了会存在事务的并发问题,那么接下来看一看,MySQL给我们提供的事务隔离级别分别解决了什么问题

MySQL定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。


1、读未提交(read-uncommitted)


在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读。


2、不可重复读(read-committed)


事务中只能看到已经提交事务的数据,这种隔离级别不支持不可重复读,如果有其它事务正在处理新增并且提交了,查询前后数据不一致导致不可重复读


3、可重复读(repeatable-read)


MySQL的默认的事务隔离级别(简称:RR),它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过还是没有解决幻读的问题。后面我们会分享关于

InnoDB存储引擎通过多版本并发控制(Multiversion Concurrency Control 简称MVCC)

机制解决了该问题。


4、串行化(serializable)


这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,解决所有并发问题。由于牺牲了并发能力,而且非常占用资源,实际开发中不会选择该级别的事务隔离。


不同事务隔离级别分别解决的并发问题参照表:

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)



版权声明:本文为hekeyer原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。