ACID 原子性 一致性 隔离性 持久性
为了解决脏读、不可重复读、幻读的问题
事务隔离级别
- 读未提交:一个事务还没提交时,就能被别的事务看到。
- 读提交:一个事务提交之后,它做的变更才能被其他事务看到。
- 可重复读:一起事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据时一致的。
- 串行化:后访问的事务必须等前一个事务执行完成才能继续执行。
可重复读事务隔离的实现
可重复读事务的实现是基于数据库的多版本并发控制(MVCC)。每个事务启动都会有生成一个read-view。
长事务会导致系统存在很老的事务视图,所以尽量不要使用长事务。
显示启动事务:begin或者start transaction ,提交:commit 回滚:rolback
set autocommit=0,关闭自动提交。只执行一个select事务就会启动,直到主动执行commit或者rollBack。
transaction id
InnoDB每个事务都有一个唯一事务ID,叫做transaction id,事务开始的时候向InnoDB的事务系统申请的,是按申请顺序严格递增的。
每行数据也都是有多个版本的。每次事务更新数据的时候,都会生成一个新的数据版本,并把transaction id赋值给这个数据版本ID,记为row trx_id,同时旧的数据版本要保留。
InnoDB为每个事务构造一个数组。用来保存这个事务启动瞬间。数组里面事务UD的最小值记为低水位,当前系统里已经创建过的事务ID的最大值+1记为高水位。
这个视图数组和高水位就组成当前事务的一致性(read-view)。
当前读
更新数据都是先读后写,这个读,只能读当前的值,称为“当前读”
select语句如果加锁,也是当前读。
可重复读
可重复读的核心就是一致性读(consistent read)
可重复读隔离级别下,只需要在事务开始的时候创建一致性视图,之后事务里的其他查询都共用这个一致性视图。
在读可提交隔离级别下,每一个语句执行之前都会重新计算出一个新的视图。
事务启动的时候还要保存“现在正在执行的所以事务ID列表”防止transaction id小于当前的transaction id的事务去更新row
幻读
GAP 间隙锁
间隙锁和行锁合称next-key lock
间隙锁和next-key lock的引入,帮我们解决了幻读的问题.
两个线程同时获取间隙锁,可能导致死锁,死锁检查影响了并发度.
