美文网首页工作中源代码学习数据库知识学习
集群并发-更新库存,验证用分布式锁的必要性

集群并发-更新库存,验证用分布式锁的必要性

作者: ___TheOne___ | 来源:发表于2023-07-17 13:53 被阅读0次

1. 背景

点餐项目开发"优惠券需求",用户领取优惠券时、额外增加优惠券库存时,都更新库存值。另外项目是 集群部署
那么集群并发-更新库存,是否有使用分布式锁的必要性?

2. 猜想

答:有必要加Redission分布式锁。

    // 语句中 【stock - i >= 0】,防止优惠券超发
    @Transactional(rollbackFor = Exception.class)
    @Modifying(clearAutomatically = true)
    @Query(value = "update t_coupon set stock = stock - ?1 where id = ?2 and stock - ?1 >=0", nativeQuery = true)
    int deductionCount( int i,Long id);

Pgsql数据库,通过语句SHOW transaction_isolation; 可知事务默认隔离级别为 read committed【读提交】
虽然上述扣减库存的update语句,显式加了事务注解@Transactional,
但还是会出现集群并发扣减时,更新被覆盖-数据不一致的问题。

【执行场景设想】
两个事务同时针对同一个优惠券库存量执行扣减操作,它们都希望将库存值减1。

  • 事务A读取库存当前值,假设为10,然后减少1,得到9。
  • 但在事务A将结果提交到数据库之前,事务B也读取了字段的当前值,仍然是10,并将其减少1,得到9。
    最后,事务A 和 事务B 都将 值9 写回数据库,导致最终结果不正确。

3. 验证

  • 创建一个优惠券,初始库存设置为1000;
  • 书写一个测试验证接口,每请求一次,对应优惠券库存扣减1
    【Dao方法先只加事务注解,暂时不加分布式锁】;
  • 使用Jmeter压力测试
    启动1000个线程,并发调用接口扣减库存。

【最终结果】
Jmeter压力测试后,此优惠券的库存量为191,并非预想中的0
直接验证了集群并发-事务中更新库存,添加分布式锁的必要性!

  • 后续将 优惠券扣减1的代码,适用Redission锁进行控制,再次执行Jmeter压力测试,最终此优惠券的库存量为预期的0。
    【没有出现集群并发更新覆盖、也没有出现超发】。

4. 思考

  • 虽然使用分布式锁解决了问题,但相应的只要是锁,就会带来性能开销,所以应尽可能减小锁的范围
    分布式锁应只包裹更新优惠券库存代码。
    如果优惠券库存更新成功,才插入用户-优惠券记录。
  • 优惠券场景下,需考虑的场景:
    1> 某一个用户领取某一个券时,加分布式锁-串行执行,防止券被超领;
    Eg: String userCouponKey = "COUPON:USER:KEY" + tenantId + userId + couponId;
    
    思考:考虑到后续有 针对某一个用户可“一键领取”多张优惠券,所以锁粒度应为 “租户id + 用户id + 优惠券id”。使得某一个用户领取不同的券是可以并行领取。
    若所锁粒度为“租户id + 用户id”,某一个用户领取多个券只能串行执行效率低下,不符合需求。
    2> 某一个优惠券超发限制(即防止优惠券库存stock为负数);
    3> 集群并发-更新库存量,并发控制。
    Eg: String couponStockKey = "COUPON:STOCK:KEY" + tenantId + couponId;
    

相关文章

  • 使用Redis实现分布式锁

    分布式锁介绍 高并发场景检查会用到分布式锁,比如秒杀场景库存控制等。一般分布式锁有几种实现方式 数据库实现 zoo...

  • java锁的概念

    参考文档探究分布式并发锁并发编程-锁的发展和主流分布式锁比较总结从构建分布式秒杀系统聊聊分布式锁探索并发编程(六)...

  • redis 分布式锁

    最近抽空优化了之前已有的redis分布式锁,主要用于解决高并发的问题,比如抢红包,多个人同时操作红包库存,当在库存...

  • 关于秒杀的方案设计思路

    限流(令牌桶) 接口隐藏(防刷) 分布式锁 用,先读缓存库存,没有则读数据库库存,做库存计算<精准>,改缓存库存;...

  • Redis个人学习总结

    Redis学习 Redis(缓存、分布式锁、支持高并发、限流、过滤、集群) 1. redis是单线程结构、支...

  • etcd:一款比Redis更骚的分布式锁的实现方式!用它

    分布式锁 关于为什么要有分布式****锁这个东西,欢迎阅读我的zk分布式锁的实现,介绍了单机高并发、分布式高并发的...

  • Redis实现分布式锁

    一、分布式锁是啥? 单机锁的概念:我们正常跑的单机项目(也就是在tomcat下跑一个项目不配置集群)想要在高并发的...

  • 使用JVM提高秒杀系统性能

    前提 使用redis分布式锁,解决秒杀系统库存为零 继续扣减问题 redis分布式锁出现的问题 使用redis锁,...

  • 干货分享:五分钟教你解决高并发场景下的订单和库存处理方案

    介绍 前提:分布式系统,高并发场景商品A只有100库存,现在有1000或者更多的用户购买。如何保证库存在高并发的场...

  • 订单和库存处理方案

    介绍 前提:分布式系统,高并发场景商品A只有100库存,现在有1000或者更多的用户购买。如何保证库存在高并发的场...

网友评论

    本文标题:集群并发-更新库存,验证用分布式锁的必要性

    本文链接:https://www.haomeiwen.com/subject/vckgudtx.html