mysql 抽奖设计_mysql,node.js_抽奖码设计问题,mysql,node.js - phpStudy

在高并发情况下,原始的MySQL抽奖码分配方案导致重复码值问题。通过改进SQL更新语句并引入affectedRows判断避免了重复,但仍有部分用户无法获取码值。最终采用Redis缓存解决超时和重复问题,定时任务补充Redis中的码库存。尽管目前运行稳定,但寻求最佳实践以优化数据库设计和程序结构。
摘要由CSDN通过智能技术生成

抽奖码设计问题

程序的逻辑:

程序事先生成了抽奖码存在mysql中,然后有用户来的以后,找到一个没有用过的抽奖码给他,然后把这个抽奖码设置成为已经使用过了

问题:

当大量用户同时并发请求的时候,大部分用户返回同一个抽奖码

原因大概是这样子的

select codeid,codevalue from tb_code where isused=0 Limit 1

通过上面的sql找到一个没有使用过的抽奖码

update tb_code set isused=1 where codeid=codeid

然后上面的sql语句是更新为已经使用

当大量用过过来的时候,比如A先取到一个码XYBV,但是还没有更新,B用户也过来了的时候找到的也是这个码值了。

code的返回都是在执行完update以后返回

后来修改了下更新语句

update tb_code set isused=1 where isused=0 and codeid=codeid

根据affectedRows来判断是不是更新成功了,如果成功的话,则返回code,否返回一个null

这样虽然不会返回重复的值,但是会有一部分收不到码值

再后来的搜了下,使用直接更新查找到码值,最后再通过ranomno来查找刚才更新的码值,如下面所示的sql

update tb_code set isused=1,randomno='+randomno+' where codeid in ( select

codeid from (select codeid from tb_code where isused=0 Limit 1) as

arbitraryTableName)';

刚开始本地测试的时候,没有问题,想着解决了。后来上线,检测日志的时候,发现很多请求长时间没有响应,应该是上面的sql语句执行的效率太低了。

最后换了一种方法使用redis缓存code

先从库里面取1000个code使用Lpush放去redis里面去,然后当用户有请求过来,直接从redis里面取Rpop

然后做一个定时任务,检测redis里面的code数量,如果少于设定的数量,就从库里面取1000个Lpush到redis里面去

现在项目跑了几个小时,暂时没有发现请求超时的问题和码值重复的问题。

但是感觉这种方式凑合能用,但不是最好的

想请问大家,对于类似的问题有没有最佳实践,比如在数据库设计和程序结构上

相关阅读:

css3 transform transition 配合缩放,字体大小变化的问题 ?

关于盒模型的几个问题

关于springmvc扫描Controller类的问题

afnetworking中的URLConnectionOperation为什么要实现NSCoding, NSCopying协议

JS中的一个奇异问题

golang中msgpack序列化array问题

关于C++类中++的运算符重载问题,后置自增表达式不行?

storm问题求助!

php框架yii组件如何保证生成代码整齐、不杂乱、优雅

ORACLE添加调试信息这个操作对包有什么影响?

echart 点击事件获取值刷新

php无限分类怎么分页?

ssh源码哪个比较容易入手?

如何插入大量数据到数据库?

Java、Guava:如何按照此种形式拼接字符串呢?

关于select option宽度问题。

类似微信底部发现图标在有新的朋友圈时,会出现一个小红点,这样的功能是怎么实现的?

JS能检测到电脑浏览器是否缩放吗?

这个 bash 脚本是如何加密的?

闭包中外层函数未被直接引用的变量何时被 GC 回收

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值