InnDB存储引擎中的锁 以及 脏读 不可重复读 幻读

来源:互联网 发布:json的解析方法 安卓 编辑:程序博客网 时间:2024/06/05 21:59

1、锁的类型

共享锁(S Lock),允许事务读一行数据。

排他锁(X Lock),允许事务删除或更新一行数据。


s和x锁都是行锁


此外,InnoDB存储引擎支持多粒度锁定,这种锁定允许事务在行级上的锁和表级上的锁同时存在。为了支持在不同粒度上进行加锁操作,InnoDB存储引擎支持一种额外的锁方式,称之为意向锁(Intention Lock)。意向锁是将锁定的对象分为多层次,意向锁意味着事务希望在更细粒度上加锁。


InnoDB存储引擎支持意向锁设计比较简练,其意向锁即为表级别的锁。设计目的主要是为了在事务中揭示下一行将被请求的锁类型。其支持两种意向锁:

意向共享锁(IS Lock):事务想要获得一张表中某几行的共享锁。

意向排他锁(IS Lock):事务想要获得一张表中某几行的排他锁。



2、锁算法

InnoDB存储引擎有3种行锁的算法,其分别是:

Record Lock:单个行记录的锁

Gap Lock:间隙锁,锁定一个范围,但不包含记录本身

Next-Key Lock:锁定一个范围,并且锁定记录本身



3、锁问题

1. Read Uncommitted(读取未提交内容) 
读取未提交的数据,也被称之为脏读(Dirty Read),是指一个事务读到了另一个事务中未提交的数据,显然违背了数据库的隔离性
2. Read Committed(读取提交内容) (不可重复读)

不可重复读是指在一个事务内多次读取同一数据集合。在事务还没有结束时,另外一个事务也访问该同一集合,并做了DML操作。因此,在第一个事务中读到的两次数据,由于第二个数据的修改可能会不一样。
3. Repeatable Read(可重读) 
这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。 

幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。 
4. Serializable(可串行化) 
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。 

在MySQL中,实现了这四种隔离级别,分别有可能产生问题如下所示:

隔离级别脏读不可重复读幻读Read Uncommitted√√√Read Committed×√√Repeatable Read××√Serializable×××


测试

1、脏读

客户端A:设置为read-uncommitted


客户端B


客户端A;


客户端B



发现出现了脏读

所以讲


2.不可重复读




客户端A,,此时还没有提交


客户端B,可以看出避免了脏读



客户端A提交



客户端B,f发生了改变,出现不可重复读现象




3、幻读

事务A


事务b



事务A



然后将事务级别设置为serializable

原创粉丝点击