【转】MySQL乐观锁在分布式场景下的实践
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了【转】MySQL乐观锁在分布式场景下的实践,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3423字,纯文字阅读大概需要5分钟。
内容图文
如图所示,如果更新操作如第一个图中一样顺序执行,则数据的版本号会依次递增,不会有冲突出现。但是像第二个图中一样,不同的用户操作读取到数据的同一个版本,再分别对数据进行更新操作,则用户的A的更新操作可以成功,用户B更新时,数据的版本号已经变化,所以更新失败。
代码实践
我们对某个商品减库存时,具体操作分为以下3个步骤:
-
查询出商品的具体信息
-
根据具体的减库存数量,生成相应的更新对象
-
修改商品的库存数量
为了使用MySQL的乐观锁,我们需要为商品表goods加一个版本号字段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;
Goods类的Java代码:
* 商品名字 */ private String name; /** * 库存数量 */ private Integer remainingNumber; /** * 版本号 */ private Integer version; @Override public String toString() { return "Goods{" + "id=" + id + ", name=‘" + name + ‘\‘‘ + ", remainingNumber=" + remainingNumber + ", version=" + version + ‘}‘; } }
GoodsMapper.java:
public interface GoodsMapper { Integer updateGoodCAS(Goods good); }
GoodsMapper.xml如下:
<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>
GoodsService.java 接口如下:
public interface GoodsService { @Transactional Boolean updateGoodCAS(Integer id, Integer decreaseNum); }
GoodsServiceImpl.java类如下:
@Service public class GoodsServiceImpl implements GoodsService { @Autowired private GoodsMapper goodsMapper; @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; } }
GoodsServiceImplTest.java测试类
@RunWith(SpringRunner.class) @SpringBootTest public class GoodsServiceImplTest { @Autowired private GoodsService goodsService; @Test public void updateGoodCASTest() { final Integer id = 1; Thread thread = new Thread(new Runnable() { @Override public void run() { goodsService.updateGoodCAS(id, 1); //用户1的请求 } }); thread.start(); goodsService.updateGoodCAS(id, 2); //用户2的请求 System.out.println(goodsService.selectGoodById(id)); } }
输出结果:
Goods{id=1, name=‘手机‘, remainingNumber=10, version=9} Goods{id=1, name=‘手机‘, remainingNumber=10, version=9} success fail Goods{id=1, name=‘手机‘, remainingNumber=8, version=10}
代码说明:
在updateGoodCASTest()的测试方法中,用户1和用户2同时查出id=1的商品的同一个版本信息,然后分别对商品进行库存减1和减2的操作。从输出的结果可以看出用户2的减库存操作成功了,商品库存成功减去2;而用户1提交减库存操作时,数据版本号已经改变,所以数据变更失败。
这样,我们就可以通过MySQL的乐观锁机制保证在分布式场景下的数据一致性。
以上。
原文链接
https://segmentfault.com/a/11...
【转】MySQL乐观锁在分布式场景下的实践
标签:int enum innodb app where 后端服务 情况下 varchar 部署
本文系统来源:https://www.cnblogs.com/zdd-java/p/8434796.html
内容总结
以上是互联网集市为您收集整理的【转】MySQL乐观锁在分布式场景下的实践全部内容,希望文章能够帮你解决【转】MySQL乐观锁在分布式场景下的实践所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。