事务的隔离级别

前言

并发事务会出现一写三读问题,丢失修改 & 脏读/不可重复读/幻读。丢失修改是一定要解决的,而三种读问题可根据情况调整不同的隔离级别,解决相应的读问题。

一、事务是什么?

一组操作数据的逻辑,要么都成功,要么都失败。这一组逻辑可以是数据库的SQL片段,也可以是磁盘上的文件操作等等。

但事务有更加严格的定义,ACID!

A)原子性,指一组操作是不可分割的部分,要么都做,要么都不做。

C)一致性,从一个一致性状态转到另一个一致性状态,就好比转账事务执行前后,所有相关帐上的总额是一致的相等的,而不同的状态下有不同的余额分布。

D)持久性,事务一旦提交,是不受任何事务执行/数据库故障的影响,持久化在磁盘上。

I)隔离性,指的是多个事务执行相互不受干扰,事务内部操作的数据是对其他事务隔离的,就像副本一样。

二、事务的隔离级别

事务的隔离级别主要是针对数据访问进行隔离,多事务并发访问会出现3种都问题,所以一共有4种隔离级别。

1、三种读问题

1)脏读,读到其他事务还未提交的数据,如果该事务rollback了,那么这就是个脏数据。

2)不可重复读,先读一个数据,让后该数据被其他事务修改,且commit了,那么再读时,就和之前读的数据不一致。

3)幻读,当前事务得到一批符合条件的数据,但是另一个事务在这个条件内又insert了一些数据,当前事务再修改这批数据后再获取数据,发现数据变多了。(因为修改数据必须要当前读,否则会出现丢失修改,而当前读就会读到新加入的数据。)

2、四种隔离级别

1)read uncommited,读未提交,最基本的隔离级别,存在脏读/不可重复读/幻读三种问题。

2)read committed,读已提交,这样就读不到未提交的数据,即读不到脏数据。

3)repeated read,可重复读,当前事务执行时间内读的数据都是一样的。不同数据库实现的方式不一样,MySQL用MVVC以事务id+副本undo log + read view来实现;有的数据库是加读写锁,以及读锁的释放时机来实现的。

4)串行化,解决脏读/不可重复读/幻读问题,事务依次串行执行。不同数据库实现不一样,有的数据库是通过提前申请所需要的所有锁;MySQL是采用MVCC + 间隙锁 / 行锁来实现。

三、MVCC

MVCC是MySQL实现读已提交 & 可重复读的一种乐观锁实现。多版本并发控制,顾名思义,采用多版本的副本来做到数据访问的隔离。

  1. 每条数据都有一个修改 / 删除版本号,这个版本号为那个事务干的,就填那个事务的版本号。有很多事务操作过,所以会形成undo log操作链。

  2. 事务的版本号如何获取?数据库有个递增版本号,每来个事务,就自增1。

1、MVCC 实现 read committed

每次读之前生成一个read view,一个当前还在进行的事务版本数组。

并秉持着 当前read view最大值之前的已提交事务对当前事务数据可见 的原则。

举个例子,当前事务id为100,获取当前read view数组为[99 101 104],那么{1 - 98,100,102,103}如果这些事务操作过指定数据,那么是对当前事务可见的。直接根据undo log链反向寻找到第一个满足条件的数据即可。

注:由于事务是并发的,undo log链不是有序的,找到一个最新鲜且可见的数据即可。

2、MVCC 实现 repeated read

read view 只生成一次!根据执行的命令不同,read view获取时间不同,可能在事务开启时,可能在第一条查询SQL执行时。(start transaction 与 start transaction with snapshot的区别

实现方式和read committed 一致,唯一区别就是read view 只生成一次,保证其可重复读。

3、MVCC + 间隙锁实现 串行化

如果是非唯一索引,才会同样的筛选条件,查到更多的数据,所以需要间隙锁来进行范围锁住。

当该查询字段是唯一索引时,不存在多个数据,所以直接用行锁即可。

总:如果加上了间隙锁 / 行锁,锁住可插入的位置,那么就不会出现幻读问题了。

总结

1)事务严格定义的四个特性,ACID,原子性 / 一致性 / 持久性 / 隔离性。

2)事务的3种读问题 & 4种隔离级别,脏读 -> 不可重复读 -> 幻读,读未提交 -> 读已提交 -> 可重复读 -> 串行化。

3)MVCC的实现读已提交 & 可重复读,以及避免脏读的解决方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值