问题
- 脏读, 读取了未提交的数据。
A事务修改,B事务读取,A事务回滚 - 不可重复读,B事务修改了一批数据,这时候A事务提交了同一批数据范围内的数据修改,B再读取,发现修改并未生效。
A事务修改,B事务读取,A事务提交,B事务读取 - 幻读 两次读取的数据条数不一样。
A事务读取,B事务插入,A事务读取
级别
- read-comited 读取已提交的数据,可以避免脏读
- repated-read 读取后加锁,可以避免脏读,不可重复读
- serizelize 读取,写入都加排他锁,避免所有
原理
- read-comited
写数据的时候加上X锁, 直到事务结束, 读的时候加上S锁, 读完数据立刻释放。(共享锁规则1) - repated-read
写数据的时候加上X锁, 直到事务结束, 读数据的时候加S锁, 也是直到事务结束。(共享锁规则2) - serizelize
写数据的时候加上X锁, 直到事务结束, 读数据的时候加X锁, 也是直到事务结束。
MVCC
MySql实现可重复度,使用了MVCC,就是快照。给每一行记录对应一个快照,每一个事务对应一个版本。对于一个快照,他可以读取哪些版本,遵循以下规则:
1.当前事务内的更新,可以读到
2.版本未提交,不能读到
3.版本已经提交。但是是在快照创建后提交的,不能读到
4.版本已经提交。但是是在快照创建前提交的,可以读到
可重复读仅在事务开始时创建一次快照
读已提交每次执行语句的时候都创建一次快照
间隙锁
- msyql解决幻读的情况
- 因为是B+树所以,在查询一段数据的时候,会把前一段和后一段数据也同时加锁,这样就无法插入数据。避免了幻读。
网友评论