mysql innodb下的锁及隔离级别

innodb引擎支持行级锁。

锁实现了事务之间的隔离功能。

悲观锁,排他锁种类:

  1. row-level lock 或record lock    都是指的行级锁

  2. gap                 间隙锁

  3. next-lock              下键锁

隔离级别(隔离的是数据的读,默认的级别是RR模式):也称读的隔离性级别

查看数据库当前隔离级别:select @@tx_isolation;

  1. RU  读未递交,出现脏读.  即读取到了内存脏页中的数据

  2. RC  读已递交,出现不可重复读,也出现了幻读,隔离了脏读

  3. RR  可重复读,解决了不可重复读,利用undo的快照技术;

      也会有幻读,但是利用GAP间隙锁+nextlock下键锁可以解决幻读现象,

      该种级别下(利用的MVCC机制),每开启一窗口都会有一undo快照,不论其它窗口中如何修改数据,

      在当前窗口中查到的数据都不会有任何变化,除非重新登陆。

      MVCC多版本控制机制,就是利用undo快照来实现的。

  4. SE  串行化,可以防止死锁,但并发事务性能差

配置文件中设置隔离级别:vim /xx/my.cnf中添加

  1. transaction_isolation=read-uncommitted

  2. transaction_isolation=read-committed

  3. transaction_isolation=repeatable-read

脏读讲解:

  发生于RU模式下,即读取到了内存脏页中的数据,叫脏读;

不可重复读讲解:

  发生于RC模式下,在一个窗口中不断的修改数据并递交,在另一个窗口中每次查询都能查到最新的数据值

  这种现象叫做不可重复读。

可重复读讲解:

  发生于RR模式下,在一个窗口中不断的修改数据并递交,在另一个窗口中每次查询的结果都是最原始的数据

  除非另一个窗口断开重连(或手动commit下),才能看到修改值。注意前提:登陆好两个窗口后不要断开重连。

幻读讲解:

  发生于RC和RR模式中,在窗口1中使用范围修改A列的值,窗口2中又插入了此范围的数据,且窗口2先于

  窗口1递交事务,当窗口1中的范围修改执行完成并递交后,查询此范围数据时,会看到A列值不全为修改值,

  即看到了窗口2中新插入的数据A列值未被修改。

  不可重复读和幻读的区别:

    不可重复读表现为某行数据一直在发生变化

    幻读表现为统一修改范围内列值后对修改期间插入的数据不受影响。

  解决幻读的必备条件(范围条件比如为id>5的数据):

    1. 处于RR模式;

    2. GAP间隙锁和nextlock下键锁不是真正的记录锁,不会锁定数据行,只锁定索引列。所以必须为索引列

     利用GAP锁锁定现有id>5范围内一些不连续的间隔,不允许对间隔数据写入

     利用nextlock锁定大于5范围内最大值后的数据,不允许写入大于当前最大id值的数据。

     GAP和nextlock锁是在满足以上2个条件时自动上锁的,之前在RC模式中窗口2中可毫无阻挡的插入范围内数据,

      现在满足以上2条件,再插入时会阻塞在原地。