1、innodb锁机制:
原理:不是对记录加锁,是对索引加锁,如果sql没走上索引,则锁全表
不走索引的情况: RC 级别下的事务A,只要A的UPDATE语句完成了(事务未必完成),其它事务可以修改A中也扫描过的行,但在 RR 级别下不允许
共享锁(S):读不阻塞别的读,阻塞别的写
排他锁(X):写的时候阻塞所有读写
意向共享锁(IS):取得共享锁之前必须先取得意向共享锁
意向排他锁(IX):取得排他锁之前必须先取得意向排他锁
2、四种事务隔离级别:
Read Uncommitted :所有事务都可以看到其他未提交事务的执行结果。会产生脏读(读取未提交数据)
Read Commited:这是公司采用的隔离级别,一个事务只能看见已提交事务所做的改变,避免了脏读。但是由于同一事务的其他实例在该实例处理期间可能会有新的commit,所以同一select可能返回不同的结果(事务中2次查询之间更新了数据)
Repeatable Read:默认隔离级别,确保同一事务的多个实例在并发读取数据时,会看到同样的数据行(实际上就是读取时加锁,阻塞)。但是会产生幻读(事务中2次查询之间插入新的数据)
Serializable:串行,没啥好说的
Read Commited 和 Repeatable Read的区别:Read Commited级别下,select不会阻塞update,2次select之间可能数据会被update掉。Repeatable Read保证了一个事务中的多次select值一致
在 REPEATABLE-READ 级别,事务持有的每个锁在整个事务期间一直被持有。
在 READ-COMMITED 级别,事务里面特定语句结束之后,不匹配该sql语句扫描条件的锁,会被释放。
幻读和不可重复读的区别:
不可重复读重点在于update:两次select之间有update修改了数据,造成读出结果不一致
幻读重点在于insert:两次select之间有新数据insert,导致两次读取记录数不一致(select无法阻塞insert)
MVCC实现可重复读,但解决不了幻读,解决幻读的方式是间隙锁
3、MVCC与一致性非锁定读/锁定读
一致性非锁定读:一条记录被加了X锁其他事务仍然可以读而不被阻塞,通过MVCC实现(实际上就是通过指针指向不同的undo记录实现)
一致性锁定读:通过select语句显式加X锁,从而保证特点场景下数据一致性