mysql高级之锁(2)

版权声明:我想应该是对的,不对的地方,希望读者能指出来! https://blog.csdn.net/tuesdayma/article/details/81910117

表锁:

可以看我上篇博客:https://blog.csdn.net/tuesdayma/article/details/81901679

行锁

概述: 行锁主要正针对于innodb(mysql5.5之后默认存储引擎)的存储引擎而言的,每次对数据库操作都会进行行锁。

特点:

1、开销大,加锁慢,会出现死锁;发生锁冲突的概率低,并发度很高。

2、会产生间隙锁,从而导致程序无法插入问题。

3、无索引或者索引失效的记录会变成表锁。

4、个人觉得,行锁没有读写锁之分,至少测出来没有。

优化建议:

1、尽可能所有的查询条件都使用索引,避免从行锁变成了表锁。

2、尽量缩小更新范围,避免出现间隙锁。

3、合理设计索引,避免出现表锁。

演示

结论1:其他session没法读取其他session中未提交的事务(mysql默认事务级别是可重复读,不会出现脏读)
这里写图片描述
结论2:当前session更新之后不提交的话(即行锁不释放的话),其他session是无法进行更新操作的。
这里写图片描述
补充1:上图也可以看到,其实第二个session执行update操作已经超时了,那么当前session提交事务之后能不能执行第二个session的update操作呢,显然是不行了。。。
这里写图片描述
补充2:如果当前session提交的延迟较小,其他session的update操作还是能进行的。这里有个Lock wait timeout的概念。
这里写图片描述

结论3:索引失效或者无索引的话,行锁将变成表锁。(我们增加一个deptno这个varchar类型的字段,然后减伤索引)

alter table test03 add deptno varchar (3)  default '111';
create index index_deptno on test03(deptno);

这里写图片描述
这里写图片描述
这里写图片描述

间隙锁:当我们where条件是一个范围,而这个范围中并不存在的记录,innodb也会对其进行加锁,这就是间隙锁(Next-Key锁),这些不存在的记录成为间隙(GAP)。
这里写图片描述
分析:当session1执行所有deptno修改的时候,age=2的那条记录虽然不在,但是也上了锁,这就是间隙锁,这时候如果其他session对间隙锁中的记录进行编辑的话,是会进入阻塞状态的,直到session1提交事务或者超时。如果未超时还是能正常执行的,但是结果中的deptno是不会变了的,新增是能成功的!

危害:当锁定一个范围之后,即使不存在的记录也不会被锁定,从而导致其他session无法进行插入范围之内不存在的记录。

如何手动锁定一行:
这里写图片描述
释放行锁: 在没有超时的前提下,其他session的update操作执行了。
这里写图片描述
结论4: 行锁是针对编辑操作的,对查询操作是不起作用的。
这里写图片描述
分析行锁:show status like 'innodb_row_lock%';
这里写图片描述
Innodb_row_lock_current_waits:当前正在等待的锁

Innodb_row_lock_time:从系统启动到现在锁定总时间长度

Innodb_row_lock_time_avg:每次等待所花平均时间

Innodb_row_lock_time_max:从系统启动到现在,等待最长一次所花的时间

Innodb_row_lock_waits:系统启动到现在总共等待的次数

猜你喜欢

转载自blog.csdn.net/tuesdayma/article/details/81910117