大致需求是这样:
数据库有一个表,生成了1万个(后面更多)唯一抽奖码,用户点击抽奖的时候会分配一个抽奖码,要求每个用户拿到的不一样,用户每拿到1个抽奖码之后会把抽奖码的状态改为已使用之类的,在没有大量并发的情况下是正常使用的,现在就是考虑并发的情况下可能两个用户拿到的是一个抽奖码,想听听大伙的解决方案,谢谢。。

解决方案 »

  1.   

    几个方案:
    1、只用数据库:
    while(true){
      获取一个码a
      update tb set status=已使用 where 码=码a and status=未使用
      if(更新成功)break;
    }
    return 码a2、增加队列
    初始化:把一万个码全部放入队列里。
    抽奖:
    码a = 队列.pop();
    update tb set status=已使用 where 码=码a and status=未使用
    if(更新成功)return 码a
      

  2.   

    上面的方案1使用了数据库的锁机制,只保证数据分配唯一性,不保证并发;方案2可以在队列pop 1万次后,后续进入的用户全部失败,对数据库压力小一些,但是引入了mq,复杂度高了。
      

  3.   

    不用mq用redis也可以的,2个队列,一个存未被抽取的,一个存已抽取未落db的,pop队列时检验动态维护队列大小,避免构造太大的队列。
      

  4.   

    首先,讲一下纯数据库如何实现,使用乐观锁(抽奖码状态),每次读取第一条未使用的数据,修改的时候 抽奖码ID + 状态=未使用 做为修改条件,这样可以解决脏读的问题,如果修改失败,则证明该抽奖码已经被使用,重复读取-修改操作 直到修改成功考虑性能,可以使用redis 缓存 抽奖码
      

  5.   

    目前用的是 存储过程实现的;因为涉及业务逻辑比较多。各种修改新增语句;
    redis也考虑了,有个问题就是,如果1万个抽奖码(后面会更多)都缓存在redis里面,如果做到和数据库很好地同步呢?
      

  6.   

    可不可以先全部存redis,取一个删一个,然后再更新数据库
      

  7.   

    用数据库乐观锁,加版本号,加一个version字段,每次都先查询,更新的时候只有版本号一致才更新,否则更新失败,当多个用户取到同一条数据的时候,只有一个用户能够更新成功,其他更新失败