参考链接
【1】https://xiaolincoding.com/mysql/lock/mysql_lock.html
【2】https://learnku.com/articles/39212?order_by=vote_count&
重要的锁:
-
表级锁(Table-level locks): 表级锁是对整个表进行加锁,当一个事务对表进行写操作时,会锁定整个表,其他事务则无法对该表进行写操作。MySQL的表级锁包括读锁和写锁,分别用于控制读操作和写操作。表级锁的特点是粒度较粗,锁定对象为整个表,因此会影响并发性能。
-
行级锁(Row-level locks): 行级锁是对表中的行进行加锁,当一个事务对某一行进行写操作时,只会锁定该行,其他事务仍然可以对表中其他行进行读写操作。MySQL的行级锁包括共享锁和排他锁,分别用于控制读操作和写操作。行级锁的特点是粒度较细,只锁定需要修改的行,可以提高并发性能。
-
页级锁(Page-level locks): 页级锁是对表的数据页进行加锁,当一个事务对某一页进行写操作时,会锁定该页,其他事务则无法对该页进行写操作。MySQL的InnoDB存储引擎会自动根据需要使用页级锁来实现行级锁和表级锁。
-
意向锁(Intention locks): 意向锁是在行级锁和表级锁之间的一种辅助锁,用于协调不同级别的锁之间的关系。意向锁包括意向共享锁(IS)和意向排他锁(IX),用于表示一个事务打算对表中的行或者表进行加锁的意图。
-
记录锁(Record locks): 记录锁是行级锁的一种特殊形式,用于锁定表中的某些记录。记录锁通常是在使用索引进行检索时由MySQL自动加上的,用于保证检索到的记录在事务中不被其他事务修改。
-
Gap Lock,间隙锁,锁的就是两个值之间的空隙,以防止其他事务在这个空隙间插入新的数据,从而避免幻读现象。
============================================================
知识点有点多,所以慢慢总结:
1. next-key lock (记录锁+间隙锁) 行级锁 -------- select … for update
【1】使用了 select … for update 语句,目的为了防止事务执行的过程中,有其他事务插入了记录,而幻读的问题。(避免幻读)
【2】如果没有使用 select … for update 语句,而使用了单纯的 select 语句,如果是两个订单号一样的请求同时进来,就会出现两个重复的订单,有可能出现幻读
在 MySQL 的可重复读隔离级别下,针对当前读的语句会对索引加记录锁+间隙锁,这样可以避免其他事务执行增、删、改时导致幻读的问题。
有一点要注意的是,在执行 update、delete、select … for update等具有加锁性质的语句,一定要检查语句是否走了索引,如果是全表扫描的话,会对每一个索引加 next-key锁,相当于把整个表锁住了,这是挺严重的问题。