mysql for update lock 悲观锁 解决并发问题
mysql常用的锁有for update 和 for update in share mode两种
锁的区别
- for update 我认为是悲观锁,其他事务读会被阻塞等待,写被禁止,且不准多次加锁
- for update in share mode 读取不等待,写入会被禁止,可被多次加锁
in share mode的问题
如果两个事务对同一行数据加锁很容易导致,两个事务都更新失败
使用场景
基于以上特点介绍,in share mode可以用于两个表关联时,保护主表数据不被修改,for update更适合保护单表单行数据的正确性,适合投票、提现等场景
测试验证
以下代码验证for update的作用
表maxcount中marks初始为8,每次减1,当他大于0时,将当时数据保存,类似于抽奖中控制最大奖品数的问题
tp中lock(true)会默认使用for update锁,我们每次测试修改代码即可
并发配置
使用ab发400并发
1 | ab -n 400 -c 400 http://127.0.0.1/ |
测试代码
1 | $marks = -1; |
事务+for update
这是正确的用法,我们发现数据记录都是合理的,并且数据都是按顺序记录,有效解决了并发问题
![正确1.1.JPG][1]
无事务+无锁
这时数据出现了错误,但是由于没有开启事务,性能比较强,所以并没有多记录
![错误1.JPG][2]
事务+无锁
由于开启了事务,mysql性能下降,又没有正确使用锁,在并发时多记录了数据,如果这时抽奖,发出的奖品就会过多问题严重,本来8个奖品,现在发了10个出去
![错误2.JPG][3]
[1]: https://blog.iguojin.com/usr/uploads/2018/09/972958847.jpg
[2]: https://blog.iguojin.com/usr/uploads/2018/09/2042545224.jpg
[3]: https://blog.iguojin.com/usr/uploads/2018/09/2164694590.jpg
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Dev!