一致性非锁定读
指Innodb存储引擎通过行多版本控制的方式来读取当前执行时间数据库中的行的数据。
如果读取的行正在执行DELETE和UPDATE操作,这是读取操作不会因此去等待行上锁的释放。相反地,InnoDB存储引擎会去读取行的一个快照数据。快照数据时指该行的之前版本的数据。
多版本并发控制:对于一个行记录的数据,可能快照数据不止一个,称为这种技术为行多版本技术。带来的并发控制,称为多版本并发控制(MVCC)
在事务隔离级别Read Committed和Repeatable Read下,Innodb存储引擎使用非锁定的一致性读。
对于快照数据的读取方式
- 在Read Committed事务隔离级别下,非一致性读总是读取被锁定行的最新一份快照数据。 而在Repeatable
- Read事务隔离级别下,非一致性读总是读取事务开始时的行数据版本
用以下例子解释:
会话A开启了一个事务,并读取了parent中id为1的数据,但是事务还没有结束。
此时用户再开启另一个会话B,更新了parent表中的id为1的记录更新为3,但是事务还没有提交,这样id=1的行其实加了一个X锁。
这是不管Read Committed还是Repeatable Read的事务隔离级别,显示的数据都是这样:
接着,会话B提交了上次的事务,会话A再执行select语句查询时将得到以下两种结果:
在Read Committed事务隔离级别下,由于会话B对id进行了修改,所以根据非一致性读总是读取被锁定行的最新一份快照数据,所以读取到了将是一条空数据。从数据库理论的角度来讲,这里违反了事务的ACID的隔离性
而在Repeatable Read事务隔离级别下,根据非一致性读总是读取事务开始时的行数据版本,所以读取到的将是之前的数据,即id=1,
完整的过程如下:
一致性锁定读
在默认配置下,事务的隔离级别为Repeatable Read模式,Innodb存储引擎的select操作使用一致性非锁定读。但在某些情况下,用户需要显示地对数据库读取操作进行加锁保证数据逻辑的一致性
Innodb存储引擎对于select语句支持两种一致性的锁定读操作
select…for update
select…lock in share mode
select…for update对读取的行记录加一个X锁,其他事务不能对已锁定的行加任何锁
select…lock in share mode对读取的行记录加一个S锁,其他事务可以向被锁定的行加S锁,也可以加X锁,但会阻塞