一、相关名词
|--表级锁(锁定整个表)
|--页级锁(锁定一页)
|--行级锁(锁定一行)
|--共享锁(S锁,MyISAM 叫做读锁)
|--排他锁(X锁,MyISAM 叫做写锁)
|--悲观锁(抽象性,不真实存在这个锁)
|--乐观锁(抽象性,不真实存在这个锁)
其中,共享锁和拍他所都是悲观锁,乐观锁不存在于mysql中,只是一种代码的逻辑实现,所以mysql的锁都是悲观锁。
二、共享锁和排他锁用法和特点。
共享锁用法:
lock in share mode;
排他所用法:
for update;
一个连接上了共享锁,别的连接也可以上共享锁,但不能上排他锁,
一个连接上了排他锁,别的连接不可以再上锁。
注:增删改的sql语句都是自带排他锁的,所以一个连接上了锁,其他连接的增删改操作会阻塞。
死锁的形成场景:
T1:begin
select * from table lock in share mode
update table set column1='hello'
T2:begin
select * from table lock in share mode
update table set column1='world'
当T1和T2都完加了共享锁,然后T1更新数据(排他锁),会阻塞直至T2释放锁;
T2也更新数据(排他锁),也会阻塞直至T1释放锁;由此造成死锁。
索引与行级锁的关系:
以前我也以为,行级锁,就是当你在where条件中指定一行加锁,那就是行级锁;
但事实是,如果这个条件字段是ID,那当然没问题,因为主键有索引,但是如果这个条件是没有索引的字段,例如name
,没有索引,会导致引擎进行全表搜索,所以锁也会是表级锁,而不是行级锁
select * from table where id = 1 for update;行级锁
select * from table where name = '123' for update;表级锁
以后如果还获取到了别的关于锁的只是,也会在原帖下面进行更新。