SQL的写法如下:
select*from distribute_lockwhere business_code = #{business_code,jdbcType=VARCHAR}for update
以上为主要实现逻辑,关于代码中的注意点:
- createOrder方法必须要有事务,因为只有在事务存在的情况下才能触发select for update的锁 。
- 代码中必须要对当前锁的存在性进行判断,如果为空的情况下,会报异常
8080的console日志情况:
11:49:41INFO 16360 --- [nio-8080-exec-2] c.k.d.service.MySQLOrderService: 进入了方法11:49:41INFO 16360 --- [nio-8080-exec-2] c.k.d.service.MySQLOrderService: 拿到了锁
8081的console日志情况:11:49:48INFO 17640 --- [nio-8081-exec-2] c.k.d.service.MySQLOrderService: 进入了方法
通过日志情况,两个不同的jvm,由于第一个到8080的请求优先拿到了锁,所以8081的请求就处于等待锁释放才会去执行,这说明我们的分布式锁生效了 。再看一下完整执行之后的日志情况:
8080的请求:
11:58:01INFO 15380 --- [nio-8080-exec-1] c.k.d.service.MySQLOrderService: 进入了方法11:58:01INFO 15380 --- [nio-8080-exec-1] c.k.d.service.MySQLOrderService: 拿到了锁11:58:07INFO 15380 --- [nio-8080-exec-1] c.k.d.service.MySQLOrderService: http-nio-8080-exec-1库存数1
8081的请求:11:58:03INFO 16276 --- [nio-8081-exec-1] c.k.d.service.MySQLOrderService: 进入了方法11:58:08INFO 16276 --- [nio-8081-exec-1] c.k.d.service.MySQLOrderService: 拿到了锁11:58:14INFO 16276 --- [nio-8081-exec-1] c.k.d.service.MySQLOrderService: http-nio-8081-exec-1库存数011:58:14 ERROR 16276 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.Exception: 商品100100仅剩0件,无法购买] with root causejava.lang.Exception: 商品100100仅剩0件,无法购买 at com.kd.distribute.service.MySQLOrderService.createOrder(MySQLOrderService.java:61) ~[classes/:na]
很明显第二个请求由于没有库存,导致最终购买失败的情况,当然这个场景也是符合我们正常的业务场景的 。最终我们数据库的情况是这样的:文章插图
文章插图
很明显,我们到此数据库的库存和订单数量也都正确了 。到此我们基于数据库的分布式锁实战演示完成,下面我们来归纳一下如果使用这种锁,有哪些优点以及缺点 。
- 优点:简单方便、易于理解、易于操作 。
- 缺点:并发量大的时候对数据库的压力会比较大 。
- 建议:作为锁的数据库和业务数据库分开 。
作者:公众号_程序员老猫
链接:https://juejin.cn/post/6913456598094626823
来源:掘金
【MySQL还能实现分布式锁?】
推荐阅读
- Spring Boot实现阿里云SMS短信发送功能
- 立秋后还能喝姜枣茶吗,湿气重的人能喝姜枣茶吗
- 常用的10种MySQL函数,数据处理一定用得上
- 白茶放了八年还能喝吗,海南兰贵人男人能喝吗
- Index MySQL查询合理使用索引:别让你的数据库负重前行
- MySQL底层的存储结构
- 「算法」如何实现一个简易计算器
- 招聘|专科生的“福利”来了,一事业单位将要招聘,薪资不低还能入编制
- MySQL分组查询后如何获取每组的前N条数据,你会吗?
- SpringBoot实现QQ邮箱注册和登录