本文主要是介绍mysql学习笔记(七)行锁,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
MySQL 的行锁是在引擎层由各个引擎自己实现的。但并不是所有的引擎都支持行锁,比如 MyISAM 引擎就不支持行锁。不支持行锁意味着并发控制只能使用表锁,对于这种引擎的表,同一张表上任何时刻只能有一个更新在执行,这就会影响到业务并发度。InnoDB 是支持行锁的,这也是 MyISAM 被 InnoDB 替代的重要原因之一。
两阶段锁
含义:需要时加上,不需要时不会立刻释放,等到事务结束后释放。
总结:如果在事务中要锁多个行,要把最有可能造成锁冲突,最有可能影响并发度的锁尽量往后放。
![](/images/baidian.png)
事务 B 的 update 语句会被阻塞,直到事务 A 执行 commit 之后,事务 B 才能继续执行。
死锁和死锁检查
![](/upload/202203/31/202203311920016829.png)
这时候,事务 A 在等待事务 B 释放 id=2 的行锁,而事务 B 在等待事务 A 释放 id=1 的行锁。 事务 A 和事务 B 在互相等待对方的资源释放,就是进入了死锁状态。
当出现死锁以后,有两种策略:
- 直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置。innodb中默认为50s。弊端: 等待超时,如果时间设置过长,不适合在线服务。设置过短,容易误伤正常的事务等待;
- 发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑,默认为开启。弊端:多个并发线程同时更新同一行时,死锁检测量级就比较大,导致cpu消耗大。
如何解决热点行更新导致的性能问题?
- 用业务来确保不出现死锁,临时关掉死锁检测。如果出现死锁情况,将会出现大量请求超时。非常不建议此方案
- 控制并发度。进程数得到控制后,死锁检测的成本会得到改善。如果多台客户端连接mysql时,需要在访问进入引擎之前,进行进程判断,需要对mysql源码进行修改,技术难度高。
- 优化实现逻辑。比如将本来同一行的多字段修改到多行上,这样每次更新同一行导致的冲突概率就会降低。(控制访问相同资源的并发事务量)
参考地址:
https://time.geekbang.org/column/article/70215
这篇关于mysql学习笔记(七)行锁的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!