1.锁的类型
1.1 行锁
两种行级锁:
-
共享锁(s锁,S LOCK,shared lock,读锁)
-
排它锁(x锁,X LOCK,exclusive lock,写锁)
其实一共就三种组合吧,ss,sx,xx。只要有x就不兼容,只有ss兼容。
1.2 表锁(意向锁)
两种表级锁:
-
意向共享锁(IS)
-
意向排它锁(IX)
InnoDB为了实现多粒度的锁,比如说你想申请T1表上a=2那一行的s锁,那么你需要先在T1表上申请到IS锁。比如说你想申请T1表上a=2那一行的x锁,那么你需要先在T1表上申请到IX锁。
意向锁就会阻塞全表锁请求(比如,LOCK TABLES…WRITE),其他的一概不阻塞。唯一的作用就是告诉你一声有个事务正锁着我这里几行,或者正筹划着锁我这几行。
1.3举个例子
select * from T1 where a=2 lock in share mode
先在表T1上加个IS锁,成功后会对a=2的行加S锁。
select * from T1 where a=2 for update
先在T1上加个IX锁,成功后会对a=2的行加X锁。
2.哪些操作会加锁
-
select * from T1 where a=
-
select * from T1 where a= lock in share mode
-
select * from T1 where a= for update
-
insert into T1 values(…)
-
update T1 set xxx where a=
-
delete from T1 where a=
上面的哪些语句会上锁,会上什么锁。
语句一什么锁都不会上。
语句二会上一个S锁
剩下的语句都会上X锁
3.gap lock 还有隔离级别
3.1 事务隔离级别
select @@tx_isolation;用来查看当前的事务隔离级别,比如我的是RR
+————————-+
| @@tx_isolation |
+————————-+
| REPEATABLE-READ |
+————————-+
Innodb定义的四种隔离级别
-
Read Uncommited
-
Read Committed(RC)
-
Repeatable Read(RR)
-
Serializable
不要蒙圈,引用哪个博客都有的一句话,四种隔离级别对数据一致性的要求一次升高。
Read Uncommited 读未提交
假设同时有事务A,事务B。
假设事务B做了一条update并且未提交,事务A已经能看见事务B做的更改了。
Read Committed(RC) 读已提交
假设同时有事务A,事务B。
假设事务B做了一条update并且未提交,事务A是看不见提交的内容的。如果事务B提交了,事务A无论是否提交都可以看见B提交的内容。凌乱了。
Repeatable Read (RR)
假设同时有事务A,事务B。
假设事务B做了一条update并且未提交,事务A是看不见提交的内容的。如果事务B提交了,事务A未提交则看不到事务B的内容,事务A提交后才能看到事务B提交的内容。
Serializable
MVCC并发控制退化为基于锁的并发控制。读加S锁,写加X锁。是的select加S锁,无论有没有尾巴都会加S锁,所以基本也不会用的。
那个经典的问题
80%面试到锁的时候都会问你这样一个问题,下面两个语句会上锁吗
select * from t1 where id=10
delete from t1 where id=10
-
组合一:id列是主键,RC隔离级别
-
组合二:id列是二级唯一索引,RC隔离级别
-
组合三:id列是二级非唯一索引,RC隔离级别
-
组合四:id列上没有索引,RC隔离级别
-
组合五:id列是主键,RR隔离级别
-
组合六:id列是二级唯一索引,RR隔离级别
-
组合七:id列是二级非唯一索引,RR隔离级别
-
组合八:id列上没有索引,RR隔离级别
-
组合九:Serializable隔离级别