1.锁的类别 和 MVCC

Shared Locks(共享锁/S锁)

A事物加S锁, B事务也可加S锁, 但是无法加X锁。 SELECT操作加S锁

Exclusive Locks(排它锁/X锁)

A事务加X锁,B事务无法加S锁和X锁。INSERT UPDATE DELETE 操作加X锁

Record Locks(行锁)

在事务中,对索引的字段加行锁。 解决幻读。

Gap Locks(间隙锁)

在事务中, 对范围锁定用间隙锁。 解决幻读。

Next-Key Locks(间隙锁)

间隙锁+行锁,原理同间隙锁一样

MVCC(多版本并发控制)

通过版本链,实现多版本。 分为快照读 和 当前读两类。

1.快照读可能是获取历史版本,不加锁

2.当前读获取最新版本,需加锁,保证并发安全

2.隔离级别原理分析

READ UNCOMMITTED
A事务读取到B事务未提交的数据(脏读现象)。 READ UNCOMMITTED级别存在 脏读,幻读, 不可重复读问题

读: 读操作全程无锁

写: 写操作在执行语句时才会加排他锁,执行完后释放
READ COMMITTED
A事务存在读取B事务update,且提交的数据(不可重复读现象)。READ COMMITTED 解决脏读,没有解决不可重复读,幻读。

脏读解决原理:通过加写锁的方式解决,写锁一直保留到事务完成后释放

不可重复读现象原理: 事务中每次执行SELECT生成快照版本(MVCC机制)。 A事务先查询,当B事务执行UPDATRE,A事务又执行相同的查询,判断B事务是否提交,如果提交则取最新版本的快照,如果不是,则取A事务查询的快照
REPEATABLE READ
A事务多次进行统计操作,期间B事务INSERT操作提交的数据,导致多次统计结果不一致(幻读现象)。 解决脏读,不可重复读 没有解决幻读(是否解决幻读不一定,下文有相关描述)。

读:在事务中第一次执行SELCT生成快照版本(MVCC机制)。解决不可重复读。

写:mysql通过innodb_locks_unsafe_for_binlog参数配置是否开启间隙锁,默认OFF 为开启。关闭间隙锁时:
      1.事务A执行SELECT, 事务B执行INSET,事务A再次SELECT,利用MVCC机制,会读取第一次SELECT快照,不会出现幻读。
      2.如果事务B在INSERT后,事务B进行UPDATE操作,并影响了事务A INSERT的数据, 则事务B再进行查询的时候会发现多出实事务AINSERT的数据,出现幻读。
      3.在开启间隙锁后会根据select条件控制insert是否加锁(间隙锁原理不过多解释),以上场景在INSERT数据时会一直为阻塞状态,等到A事务执行完成后,才会释放。
SERIALISABLE
事务串行执行,解决了脏读,不可重复读,幻读