关于mysql的一点思考

目录

1. 使用@Async多线程操作数据库担心数据不一致引发的思考


1. 使用@Async多线程操作数据库担心数据不一致引发的思考

其实这个问题一些新手CRUD程序员也会想到, 下面我模拟一个场景简单还原一下

问题还原: 现存在一张mysql的表, 表中有state字段表示状态(激活\非激活\激活中), 现在需要一个异步的方法去执行激活操作. 执行前需要判断该行state字段是否处于[非激活]状态, 若处于[非激活状态]则进行激活操作, 然后将状态设设置为[激活中], 等激活完成后更新状态为[已激活], 否则不进行激活操作. 

我的担心: 因为该操作是异步的, 假设有A和B两个线程, 如果A线程执行激活操作, 那么程序会去执行更新操作: 将state更新为[激活中], 我担心的是更新state字段为[激活中]这套动作还没完成时, B线程读取了该行state字段, 结果肯定是[非激活], 然后B线程也会执行激活操作, 这样A和B线程都执行了激活操作, 这样就存在问题了. 如果这个操作不是激活而是其他操作比如转账, 这样就肯定不行了. 

解决方案:   查阅了相关资料比如这位老铁的文章就讲的很好, 这个图片我是太喜欢了搬过来装装B

图片来自:weixin_39559071 

还有这篇关于行锁的介绍, 还有这位老哥的文章描述了一些行锁需要避免的坑, 还有这位大佬, 写的都很好, 让我受益匪浅, 我就不造轮子了, 在这引用weixin_39559071 中的一句过来方便回忆翻阅

对于UPDATE、DELETE、INSERT语句,InnoDB会自动给涉及数据集加排他锁(X) MyISAM在执行查询语句SELECT前,会自动给涉及的所有表加读锁,在执行增、删、改操作前,会自动给涉及的表加写锁,这个过程并不需要用户干预

这样看来我的担心就是多余的啦, 因为InnoDB会自动添加行锁, 那么上述的担心:A线程更新state字段操作未完成, 因为行锁存在,  B线程只能乖乖等A线程更新state字段完成四释放锁后才能进行读取. 很显然, 这种行锁是一种悲观锁, 悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性. 参考mybatisplus实现乐观锁一文.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无情的搬砖机器

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值