InnoDB存储引擎 事务隔离机制 MVCC
1、InnoDB存储引擎
""" 前文我们提到过InnoDB支持行锁(锁定字段含有索引的情况下,否则走表锁),但锁定方式并非简单的锁定指定行上的索引,而是分为3种锁定算法: 1)记录锁(Record Locks):锁定指定行的索引项 2)Gap Locks:锁定某一个范围内的索引,但不包括记录本身 3)间隙锁定(Next-Key Locks):锁定一个范围内的索引,并且锁定记录本身 Next-Key Locks = Record Locks + Gap Locks A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record 而InnoDB 存储引擎默认隔离级别为可重复读(Repeatable Read),该隔离级别下,对于索引的查询采用 next-key locks。这样做避免了幻读现象的产生。 """
2、事务隔离机制
详情参见:https://www.cnblogs.com/linhaifeng/articles/14387903.html#_label4
""" 事务具有原子性、一致性、隔离性、持久性四大特性,而隔离性顾名思义指的就是事务彼此之间隔离开,多个事务在同时处理一个数据时彼此之间互相不影响,
如如果隔离的不够好就有可能会产生脏读、不可重复度、幻读等读现象,为此,隔离性总共分为四种级别 由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题。 """
需要强调的是:我们确实可以采用提高事务的隔离级别的方式来解决脏读、不可重复读、幻读等问题,但与此同时,事务的隔离级别越高,并发能力也就越低。所以,还需要读者根据业务需要进行权衡。
""" 解决: 脏读 不可重复读 幻读 方案: RR机制+innodb存储引擎的Next-key lock行级锁算法 """
""" Repeatable Reads机制是MySQL默认事务隔离机制,解决了幻读的情况,但存在脏读和不可重复读的问题,通过innodb存储引擎内部的next-key lock来解决剩下两种读现象的问题。 """
""" 了解 事务在读取某数据的瞬间(开始读的瞬间),必须对其加行级共享锁,直到事务结束才释放,事务在更新某数据的瞬间(发生更新的瞬间),必须对其添加排它锁,直到事务结束才释放 """
3、MVCC
""" MVCC (Multiversion Concurrency Control),即多版本并发控制技术,它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,
取而代之的是,把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能. """
快照读和当前读
""" 在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。
当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。 在一个支持MVCC并发控制的系统中,哪些读操作是快照读?哪些操作又是当前读呢?以MySQL InnoDB为例: """
快照读
""" 简单的select操作,属于快照读,不加锁。(当然,也有例外,进一步了解,请点击https://www.cnblogs.com/crazylqy/p/7611069.html) select * from table where ?; """
当前读
""" 特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。 select * from table where ? lock in share mode; select * from table where ? for update; insert into table values (…); update table set ? where ?; delete from table where ?; """