zoukankan      html  css  js  c++  java
  • 解决并发问题的一般思路及使用redis实现秒杀

    解决思路
      从读到写这段时间的数据不一致问题,根源在于用户并行(个人认为并发是时间概念,并行是空间概念),
    要解决这个问题,需要让用户串行,单个用户原子性。锁 说它可以做到。
      锁只有一个目的,就是把并行变为串行,但是上锁的方式 五花八门。
      1. Java应用内存锁
        Java中自带很多内存锁,synchronize,各种Lock,但是优惠券服务多机部署,内存锁无法满足需求;
      2. Mysql数据库锁
        优惠券服务使用MySql(一个写节点),innodb存储引擎,innodb 支持 行锁。
        利用innodb的行锁机制,可以使用两种方式实现用户领券的原子性:
        第一种,读取之前上锁, 更新之后解锁
          select  ... from table where ... for update;
          update table set ....
          优点: 简单明了; 缺点: select 和 update 之间处理 出异常或应用异常终止 会产生死锁。
        第二中,利用update 锁行机制,加上where 条件 判断数据,也是读取前上锁,更新后解锁。
          update table set .... where ....
          优点:简单明了; 缺点: 效率不高
        另外更新操作直接命中数据库会对数据库产生很大的压力,所以数据库锁无法满足抢券业务;
      3. Redis分布式内存锁
        优惠券服务使用单节点Redis,Redis 支持setnx命令。
        利用setnx命令,可以在应用中自建锁及维护锁的生命周期。
        基本思路是领券前将优惠券的key通过 setnx 命令写进 redis,成功则之后便执行后续的三次读取 比较 和更新,
      最后 del 命令删除优惠券的key。
        优点:逻辑简单,实现简单,total_got,user_got,user_today_got 三个值 存哪里不受任何限制。
        缺点:不太可靠,setnx 成功后,应用出现异常,没有执行最后的del , 会产生死锁;也可以在 setnx 后再
      设置一个过期时间,是的,这是一个办法,只需要保证过期时间大于 接口的最大执行时间。
        另外,也可以使用 官方推荐的 分布式Redis锁 开源实现 Redisson。

    以redis为例:

     

     

  • 相关阅读:
    Protocol Buffer使用
    uImage、zImage、bzImage、vlinzx区别
    nginx学习之一
    Android屏幕底部弹出DialogFragment(3)
    C++11 | 正则表达式(4)
    Android绘图之渐隐动画
    Android动态Java代码调整window大小
    Spring Boot交流平台
    Java日志实战及解析
    Android WindowManager悬浮窗:不需要申请权限实现悬浮
  • 原文地址:https://www.cnblogs.com/HYV587/p/12658127.html
Copyright © 2011-2022 走看看