在innodb的事务隔离级别是可重复读级别且innodb_locks_unsafe_for_binlog禁用的前提下,MYSQl的锁机制经过测试为
1.当Update和Delete操作的时候,Mysql的加锁机制大概为三步
(1)对where条件后面的条件进行锁索引区域操作,如果没有压上索引,则整个索引进行锁索引,类似于锁表,但本质上依然是锁行。
(2)锁定指定的主键范围,如果存在主键。若不指定主键范围,且主键存在,则锁定整个主键索引。
(3)如锁定主键为一个范围,则触发next-key-lock机制,会对索引范围的头部的下一个记录进行行锁处理
注意:等于的条件会产生单条锁,其他的条件会产生范围锁
如果表为空表,会锁定全部索引 类似于表锁
2.当产生了步骤1的锁以后,如果锁所在的事务没有提交,而一个新事务做新操作如插入 删除 更新的时候,如果操作记录的主键或者索引在锁定的范围内,则会产生锁等待。
3.多线程的情况下的死锁:
(1)线程1:执行了更新了操作,获取到了非主键索引的锁,请求主键索引的锁
(2)线程2:执行了插入操作,获取了主键索引的锁,请求非主键索引的锁
(3)线程1和线程2并发执行,这时候互相等资源造成死锁
4.比较特殊的死锁情况为:
当一个空表(test_tb)中,没有任何的数据的前提下,做如下操作
(1)事务1:更新或者删除这个表
(2)事务2:更新或者删除这个表
(3)事务1:插入某个记录 (会BLOCK住)
(4)事务2:插入某个记录 (报死锁)
当两个事务拿到相同区间锁后,就会阻止对方忘区间内做insert操作。所以第一个事务insert会阻塞,第二个事务会提示死锁