一、概述:
事务隔离级别是数据库用来处理数据库高并发访问的安全性和效率性锁提供的事务处理机制,数据库是一个高并发的应用,同一时间会有大量的并发访问量,因此,理解隔离级别的底层原理,原则合适的隔离级别对数据库是至关重要的。
二、常见的并发封锁策略:一次封锁协议:预先对徐亚访问的数据对象进行全部加锁,这种方式很有效的解决了死锁的问题,但对于数据库这种大并发的应用显然是不适用的,因为在事务开始时候,事务并不知道需要用到哪些数据,即数据是变化的。
两段锁协议:在加锁阶段不能释放锁,在释放锁阶段不能加锁,两段锁协议非常适合数据库事务的加锁方式,也是目前事务正在使用的封锁策略。
虽然这种封锁策略无法避免死锁的问题,但能报保证串行化加锁和解锁,对事务的回滚和数据备份都有很大的作用。
三、innoDB中的锁策略算法:
1、记录锁算法:记录锁是锁的索引记录,不是真正的数据记录。
2、间隙锁(防止幻读)
间隙锁又叫GAP锁,隔离级别为可重复读,即是在索引的间隙加锁,禁止插入数据。
3、next-key锁;next-key锁实质也是使用了GAP锁,在进行范围检索时,主要作用是对范围进行行加锁和间隙加锁,数据库就是使用该算法进行多行扫描加锁,不但对记录加行锁,还加间隙锁。https://blog.csdn.net/xifeijian/article/details/20313977
4、插入意向锁:当多个事务同时写入数据到同一间隙时,并不需要等待其他事务完成。当若存在间隙锁,则需要等待间隙锁释放。
5、mvcc;多版本并发控制技术,innoDB中,在行记录中增加两个隐藏列,分别记录创建版本号和删除版本号,通过版本号和行锁来提高数据库系统的并发性能。但mysql中的mvcc并非真正意义上的mvcc,只是借助mvcc实现了读的非阻塞而已。MVCC中读操作分类如下:快照读:读取的历史数据,简单的 select 语句,不加锁,MVCC 实现可重复读,使用的是 MVCC 机制读取 undo 中的已经提交的数据。所以它的读取是非阻塞的。
当前读:需要加锁的语句,update,insert,delete,select…for update 等等都是当前读。
四、innoDB隔离级别的实现原理:
读未提交:读未提交是几乎不会使用的隔离级别,这种隔离级别对数据库的任何操作都不会加锁。
读已提交:读已提交对读取操作不会加锁,到对修改、更新和删除操作会加锁,
从上图可知,事务A对teacher_id=1这一行进行更新操作,因此需先对对应的行加行锁,从而导致后来的事务B中的更新操作报错。
ps:上述情况中的teacher_id是索引列,能够别唯一的确认,因此加的是行锁,若是对非索引列进行当前读操作,这时候,innoDB存储引擎无法快速的通过索引过滤出对应的行, 因此数据库会对整表加锁。在有MYSQL server进行过滤。
当然,操作《高性能MYSQL》中MYSQL server在进行过滤时候,会释放不满足条件的行锁,这样锁虽然违反了两段锁的思想,但提高了部分的效率。可重复读:innoDB默认的隔离级别为可重复读,可重复复分为“读”和“写”两部分,读取不加锁,使用MVCC来实现可重复读,写操作利用next-key锁来保证事务操作安全。
ps:可重复读中不可重复读和幻读的情况非常相似,但可重复读主要侧重于update和delete操作,幻读主要侧重于insert操作。可串行化:这个级别很简单,读加共享锁,写加排他锁,读写互斥。使用的悲观锁的理论,实现简单,数据更加安全,但是并发能力非常差。如果你的业务并发的特别少或者没有并发,同时又要求数据及时可靠的话,可以使用这种模式
× 请我吃糖~