MySQL中不同场景中排它锁的不同表现

mysql5.7 Golang的gorm做的测试

最后结论如下:

  • 按主键查询,只会锁查到的那条数据
  • 按主键加其他字段查询同上,
  • 按照非主键字段查询,查到查不到都会造成表锁
  • (以上的锁指排他锁)
  • 排它锁生效时,事务外查询(共享锁)不受影响,但查到的数据为旧版本(事务开始时)的数据
  • 修改操作访问到被加排他锁的数据会阻塞等待锁释放,等待超时会报出1205错误,("Error 1205: Lock wait timeout exceeded; try restarting transaction")

上边的结论比较笼统,找到了一个更加严谨详细的地址(https://blog.csdn.net/chenshun123/article/details/79661680 )

本人的具体需求是做一个工厂模式的任务队列以不断处理订单服务中的各种积分的交易订单,最后总结出以下几点注意事项:

  1. 如果要通过锁来保证一个任务只会被一个worker处理,加锁时用必须用id查询并且不能用like,not,!=等,会产生表锁
  2. 对用户余额的查询分为两种,一是交易前余额验证,应在事务中进行,加排它锁保证数据一致性.二是客户或其他服务查看当前余额,在事务外进行,这样做的好处是不会受锁的阻塞并且查到的是事物提交前的数据(得益于MVCC)
  3. 对于设计金融的需求,首先考虑的是安全,所以必要情况下你需要牺牲性能来保证数据准确性,我采用的悲观锁
  4. 本项目会被取代,大佬说理想解决方案是通过kafka的消息队列,感兴趣的朋友可以去看一下

 

posted @ 2019-04-16 15:42  石冠易  阅读(575)  评论(0编辑  收藏  举报