学习mysql不得不学习mysql行级锁,目前Innodb是支持行级锁的引擎,下面一起学习一下。
InnoDB 引擎是支持行级锁的,而 MyISAM 引擎并不支持行级锁。
普通的 select 语句是不会对记录加锁的,因为它属于快照读。如果要在查询时对记录加行锁,可以使用下面这两个方式,这种查询会加锁的语句称为锁定读。
1 | //对读取的记录加共享锁 |
上面这两条语句必须在一个事务中,因为当事务提交了,锁就会被释放,所以在使用这两条语句的时候,要加上 begin、start transaction 或者 set autocommit = 0。
共享锁(S锁)满足读读共享,读写互斥。独占锁(X锁)满足写写互斥、读写互斥。
什么是S锁?
在数据库管理系统和并发控制中,共享锁(通常称为S锁)是一种用于保证数据一致性的机制。它允许多个事务同时读取数据,但在持有共享锁的事务完成之前,不允许任何事务修改该数据。
共享锁有如下特点:
允许共享读取:多个事务可以同时持有共享锁,从而允许它们同时读取数据。这不会造成数据的不一致,因为没有事务可以在此时修改数据。
阻止修改:即使多个事务持有共享锁,也不能有任何事务对数据进行写入或修改,直到所有持有共享锁的事务都释放锁为止。
互斥:如果一个事务持有共享锁,则其他事务不能获得排他锁(X锁)。排他锁允许事务对数据进行修改,并会阻止其他事务对该数据进行任何类型的锁操作(包括共享锁和其他排他锁)。
什么是X锁?
在数据库管理系统和并发控制中,排他锁(通常称为X锁)是一种更为严格的锁定机制,用于确保数据的完整性和一致性。
阻止所有其他操作:持有排他锁的事务可以读取和修改数据。与此同时,其他任何事务都不能对这块数据进行读取或修改操作,直到排他锁被释放。
互斥性:在一个事务持有排他锁期间,其他事务不能获得该数据的任何类型的锁,包括共享锁和其他排他锁。这保证了对数据的完全控制,防止了并发操作引起的冲突和数据不一致。
独占访问:因为排他锁会阻止其他事务的访问,所以它适用于需要对数据进行写操作的场景,如更新、删除等。
锁升级:在某些数据库系统中,当事务需要从共享锁升级为排他锁时,可能会导致锁的升级过程,期间可能需要等待其他持有共享锁的事务完成。
Mysql 行级锁有哪些?
1. Record Lock,记录锁,也就是仅仅把一条记录锁上;
Record Lock 称为记录锁,锁住的是一条记录。而且记录锁是有 S 锁和 X 锁之分的:
例如以下语句:
1 | mysql > begin; |
事务会对表中主键 id = 1 的这条记录加上 X 型的记录锁,如果这时候其他事务对这条记录进行删除或者更新操作, 那么这些操作都会被阻塞。
注意,其他事务插入一条 id = 1 的新记录并不会被阻塞,而是会报主键冲突的错误,这是因为主键有唯一性的约束。
2. Gap Lock,间隙锁,锁定一个范围,但是不包含记录本身;
Gap Lock 称为间隙锁,只存在于可重复读隔离级别,目的是为了解决可重复读隔离级别下幻读的现象。
假设,表中有一个范围 id 为(3,5)间隙锁,那么其他事务就无法插入 id = 4 这条记录了,这样就有效的防止幻读现象的发生。
3. Next-Key Lock:Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。
Next-Key Lock 称为临键锁,是 Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。
假设,表中有一个范围 id 为(3,5] 的 next-key lock,那么其他事务即不能插入 id = 4 记录,也不能修改 id = 5 这条记录。
所以,next-key lock 即能保护该记录,又能阻止其他事务将新纪录插入到被保护记录前面的间隙中。
next-keyW lock 是包含间隙锁+记录锁的,如果一个事务获取了 X 型的 next-key lock,那么另外一个事务在获取相同范围的 X 型的 next-key lock 时,是会被阻塞的。
好了今天只是其中的一小步分暂时整理到这,后续会继续积累总结