mysql乐观锁在分布式系统中的解决方案

问题背景

在分布式系统中,应用会进行多实例部署,不同势力有各自的JVM,被负载均衡到不同实例上的用户请求通过JVM的锁机制无法互斥。例如,电商购物环节的减库存操作,有可能导致用户同时点击导致库存不一致的问题。

解决方案
  • 使用MySQL乐观锁
  • 分布式锁(暂不介绍)
MySQL乐观锁具体实现

相对于悲观锁,它只有在数据提交的时候进行冲突校验,如果产生数据冲突,返回错误信息,进行相应处理。

  • 在数据库表中添加version版本号字段
CREATE TABLE `goods` (

 `id` int(11) NOT NULL AUTO_INCREMENT,

 `name` varchar(64) NOT NULL DEFAULT '',

 `remaining_number` int(11) NOT NULL,

 `version` int(11) NOT NULL,

 PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
  • 读取数据包括版本号
  • 数据更新时对这条数据的version + 1
<update id="updateGoodCAS" parameterType="com.ztl.domain.Goods">

       <![CDATA[
         update goods
         set `name`=#{name},
         remaining_number=#{remainingNumber},
         version=version+1
         where id=#{id} and version=#{version}
       ]]>

   </update>
  • 判断数据库中要更新时的版本号和第一次取到数据的版本号是否一致,一致的话,说明更新,否则认为数据过期,返回错误信息到页面上。
 @Override
   public Boolean updateGoodCAS(Integer id, Integer decreaseNum) {
       Goods good = goodsMapper.selectGoodById(id);
       System.out.println(good);
       try {
           Thread.sleep(3000);    
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       good.setRemainingNumber(good.getRemainingNumber() - decreaseNum);
       int result = goodsMapper.updateGoodCAS(good);
       System.out.println(result == 1 ? "success" : "fail");
       return result == 1;
   }
参考

https://juejin.im/post/5afec34df265da0b745269db

转载于:https://my.oschina.net/alvinlkk/blog/1816476

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值