锁定读, 一致性非锁定读

http://ju.outofmemory.cn/entry/275548

锁定读 (Locking Reads)

在一个事务中查询数据时,普通的SELECT语句不会对查询的数据进行加锁,其他事务仍可以对查询的数据执行更新和删除操作。因此,InnoDB提供了两种类型的锁定读来保证额外的安全性: - SELECT … LOCK IN SHARE MODE - SELECT … FOR UPDATE SELECT … LOCK IN SHARE MODE: 对读取的行添加S锁,其他事物可以对这些行添加S锁,若添加X锁,则会被阻塞。 SELECT … FOR UPDATE: 会对查询的行及相关联的索引记录加X锁,其他事务请求的S锁或X锁都会被阻塞。 当事务提交或回滚后,通过这两个语句添加的锁都会被释放。 注意: 只有在自动提交被禁用时, SELECT FOR UPDATE 才可以锁定行, 若开启自动提交, 则匹配的行不会被锁定。

一致性非锁定读 (Consistent Nonlocking Reads)

MySQL官方文档对弈一致性读的定义: > A consistent read means that InnoDB uses multi-versioning to present to a query a snapshot of the database at a point in time. 就是说: 一致性读意味着InnoDB使用多版本控制来实现一个查询,这个查询所依赖的数据是基于某个时间点的数据库快照。 注意: 是数据库的快照,而不是要查询的那个表的快照。 在事务隔离级别设置为READ COMMITTED和REPEATABLE READ时,默认情况下InnoDB是通过一致性读来处理SELECT语句的。一致性读不会对它访问的表设置任何锁,因此,在一个表上进行一致性读的同时,其他session可以随意修改这些表。 一致性读是使用基于时间点的快照信息来呈现查询结果的读取操作,而不管其他事务在同一时间产生的变更。如果查询的数据已被其他事务改变,InnoDB会基于undo log的内容来重建最初的数据。 两种事务隔离级别下,读取的快照数据的区别: - 在REPEATABLE READ事务隔离级别下,同一事务内的所有一致性读都会读取到该事务中第一个一致性读建立的快照。通过提交当前事务并发起一个新的查询,可以看得到新的快照。 - 在READ COMMITTED事务隔离级别下,同一事务内的每个一致性读总是读取本次一致性读建立的快照。(即,快照的时间点是基于本次一致性读的时间点,也就是最新的数据) 假设当前事务隔离级别为REPEATABLE READ,当发出一个一致性读(也就是一个普通的SELECT语句)时,InnoDB会根据这个查询给此事务分配一个时间点。若其他事务在此时间点之后删除了一行并提交,那么此事务不会看到其他事务产生的影响(即,还是会看到被删除的行)。插入和更新操作也一样。