字有点多,但是保证你看完后对可重复读有新的理解
mysql基于乐观锁原理实现的mvcc(Multi-Version Concurrency Control,多版本并发控制)
mysql默认隔离级别就是可重复读,这个隔离级别解决了不可重复读和脏读,所谓不可重复读就是在一个事务内多次查询的结果不一样,其原因就是期间数据被另一个事务修改了;脏读就是一个事务读取到了另一个事务未提交的数据,然而该数据回滚了,实际上并未提交;
实现原理前置知识:
InnoDB是通过维护两个隐藏列来实现mvcc,隐藏列记录了数据行创建版本号和删除版本号,每开始一个事务,版本号就会递增;事务开始时刻的版本号就是事务的版本号,用来和查询到的数据行的版本号进行比较;
mvcc在可重复读级别下的具体实现:
查询:
需满足两个条件
1、创建版本号小于或等于当前事务版本,这样可以确保查出来的数据都是在本次事务开始前就已经存在,或者由本次事务创建或修改的;
2、删除版本号大于当前事务版本号或者未定义(未定义即未删除),这样可以保证在此次事务之前就存在的行没有被删除;
插入:
插入的每条数据都需要将创建版本号保存为当前事务版本号;
删除:
删除的每条数据都需要将删除版本号保存为当前事务版本号;
修改:
插入一条新数据,将创建版本号保存为当前事务版本号,并将原数据的删除版本号保存为当前事务版本号;
mysql通过维护这两个版本号,让大多数读操作都可以不加锁