目录
一、按机制:共享锁(读锁)、排他锁(写锁)
1、共享锁:
①概念:也称读锁,S锁。当事务对数据(这里的数据可以是全局库、表、行)加上共享锁后,其他事务只能对该数据进行读操作,不能进行写操作。
②用途:因为在读的时候不允许其他事务修改,所以能够解决不可重复读的问题。
③用法:
select … lock in share mode
2、排他锁:
①概念:又称写锁,X锁。当事务对数据(同上),加上排它锁后,其他事务不能对该数据进行读写操作。
②用途:因为在读写数据的的时候不允许其他事务读写,所以能够解决脏读的问题。
③用法:
select …for update
二、按粒度:全局锁、表锁、行锁
1、全局锁:
①概念:针对整个库的锁,又分全局读锁和全局写锁,读写锁和上面所介绍的读写锁的功能一致。
②用途:当需要进行一些全库导出、备份的操作时,全局锁可以有效保证数据的一致性。
③用法:
Flush tables with read lock // (FTWRL),加锁
unlock tables//解锁
2、表锁:
①概念:针对表的锁,又分表读锁和表写锁。加锁快,但锁冲突概率高。
②用途:适合一些读多写少的应用场景,适合全表删除或者更新的场景使用。
③用法:
lock tables '表名' read/write;
unlock tables//解锁
3、行锁:
①概念:针对行的锁,又分读锁和写锁,但锁冲突概率低,但更耗资源,容易死锁。
②特别地:
Ⅰ.只在事务中有效,在非事务的sql在执行完会执行释放。
Ⅱ.行锁实际上锁的是行记录的索引,如果加锁时没有用到索引,也就会进行全表扫描,从而使得行锁退化为表锁。
Ⅲ.如果加锁时用到了非主键索引,那么会先锁住非主键索引,再回表找到主键索引后再锁主键索引。
Ⅳ.如果加锁时进行了UPDATE、DELETE操作时,会进化为临键锁(next-key locking)
②用途:适合高并发读写场景、短期的锁定及复杂的事务处理场景
③用法:在事务中对单行进行以下操作时
select … lock in share mode
select …for update
insert//对当前新增行
uptdate//对当前修改行
delete//对当前删除行
三、按业务:乐观锁、悲观锁
1、乐观锁:
①概念:乐观锁在mysql中并没有内置实现,是通过编程技术手段实现的。他假设大多数情况下都不会发生锁冲突,如果发生冲突,可进行回滚或者再次重试。
②用途:适合一些读多写少,锁冲突概率较小的场景,如果写多锁冲突规律大,则会发生大量回滚或者不断重试,影响性能。
③用法:
Ⅰ.设置一个字段version
Ⅱ.每次开启事务更新前先查一便拿到当前version号
Ⅲ.更新时连同version一起更新并且条件带上version=#{verison},如果失败,则回滚.
④案例:在业务层实现
Ⅰ.查询订单信息
select id,status,version from order where id=#{id};
Ⅱ.查询其他信息并处理
...
Ⅲ.修改订单状态
update set status=支付成功,version=version+1 where id=#{id} and version=#{ version};
2、悲观锁:
①概念:悲观锁假设每次操作都会发生冲突,因此每次操作前都会加锁。
②用途:适合一些写多读少,锁冲突概率较大,或数据强一致性的场景。
③用法:在mysql中主要就是使用共享锁和排他锁实现,即
select … lock in share mode
select …for update
四、按算法:记录锁、间隙锁、临键锁
1、记录锁:即为行锁
2、间隙锁:
①概念:存在于纪录之间的间隙上的锁,作用范围为左开右开,不锁记录本身。仅在RR事务隔离级别下有效。
例如有表
id | name |
---|---|
1 | jack |
3 | mike |
5 | Mac |
则以上存在间隙锁(-∞,1),(1,3),(3,5);
当一事务select … where id=3 for update时,另一事务。insert id=2时,无法插入。
②用途:间隙锁会封锁某条记录相邻两个键之间的空白区域,防止其它事务在这个区域内插入、修改、删除数据,为了解决幻读
③用法:MySQL自身存在
2、临键锁:
①概念:是间隙锁+纪录锁的结合,即既锁记录间的间隙,作用范围为左开右闭,也锁记录本身。仅在RR事务隔离级别下有效,而且临键锁只与非唯一索引列有关,在唯一索引列(包括主键列)上不存在临键锁。
age | name |
---|---|
1 | jack |
3 | mike |
5 | Mac |
例如以上的表则以上存在间隙锁(-∞,1],(1,3],(3,5];
②用途:解决幻读问题
五、按意向:意向共享锁、意向排他锁
1、概念:两个锁均为表锁,在对表里某些记录加上共享锁之前,会先在表级别加上一个意向共享锁。
同理,在加上排他锁前。。。
2、用途:那么有了意向锁,如果想对表加锁,那么会直接查该表是否有意向独占锁,如果有就意味着表里已经有记录被加了锁,这样就不用去遍历表里的记录。也就是是为了快速判断表里是否有记录被加锁。
3、意向锁只与表锁互斥,与其他行锁不互斥。