共计 1255 个字符,预计需要花费 4 分钟才能阅读完成。
一致性非锁定读(consistent nonlocking read)
一致性非锁定读是值 InnoDB 存储引擎通过多版本控制(multi versioning)的方式来读取当前执行时间数据库中的数据。如果被读的数据行被加了排他锁,在读取这行数据的时候并不会等待锁释放,而是读取该行的一个快照数据。
之所以称为非锁定读,因为不需要等待被访问行的 X 锁的释放。快照数据是指改行之前的数据版本,该实现通过 undo 段来完成。
非锁定读的方式极大提高了数据库的并发性。在 InnoDB 存储引擎中,这是默认的读取方式。
快照数据其实就是当前行数据的一个历史版本,每行记录可能有多个版本。这种技术成为行多版本技术。由此带来的并发控制,成为多版本并发控制(Multi Version Concurrency Control,MVCC)。
在事务的隔离级别,READ COMMITED 和 REPEATABLE READ 下,对快照数据的定义不同。在 READ COMMITTED 事务隔离级别下,对于快照数据,非一致性读总是读取被锁定行的最新一份快照数据。而在 REPEATABLE READ 事务隔离级别下,对于快照数据,非一致性读总是读取事务开始时的数据版本。
也就是说在 READ COMMITTED 事务隔离级别下,非锁定读读取到的数据是最新的快照版本数据,也就是可以读到另一个事务已经提交了的快照数据。而在 REPEATABLE READ 下,只会读到事务开始前的数据。
一致性锁定读
在默认情况下,InnoDB 存储引擎对数据采用的是一致性非锁定读。但是有些情况下为了保证数据逻辑的一致性,需要对 SELECT 的操作加锁。InnoDB 存储引擎对于 SELECT 语句支持两种一致性的锁定读(locking read)操作。
1、SELECT …… FOR UPDATE
2、SELECT …… LOCK IN SHARE MODE
其中,SELECT …… FOR UPDATE 对读取的记录加一个 X 锁,其他事务不能对已锁定的行加任何锁。而 SELECT …… LOCK IN SHARE MODE 是对读取的记录加一个 S 锁。
即使被读取的行被加了一致性锁定读,如果有另一个一致性非锁定读的操作来读取该行数据是不会阻塞的,读取的是改行的快照版本。
SELECT …… FOR UPDATE 和 SELECT …… LOCK IN SHARE MODE 必须在一个事务中,当一个事务提交了,锁就释放了。因此在使用上述两个 SELECT 锁定语句时,必须开启事务。
外键锁
对于外键值的插入和更新,首先需要查找父表中的记录,即 SELECT 父表。但是对于父表的 SELECT 操作,不是采用一致性非锁定读的方式,因为这样可能会发生数据不一致的问题。此时采用过的是 SELECT …… LOCK IN SHARE MODE 的方式,给父表的记录加一个 S 锁。如果此时对父表加一个 X 锁,则会被阻塞。
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-08/146216.htm