引入redis防超抽带来的问题

业务

抽奖 每天每个用户只能抽3次

想用redis来防同一用户并发超抽 极简代码如下

count = redisService.incr(key);
if(count > 3){
//提示 抽奖次数已用完
return;
}
doBusiness();
完善代码[br]设置过期时间

Long count = redisService.incr(key );
if(count != null && count == 1){
//过期时间24小时
redisService.expire(key, 246060);
}
捕捉redis操作异常

Long count = null;
try{
count = redisService.incr(key );
if(count != null && count == 1){
//过期时间24小时
redisService.expire(key, 246060); //若执行expire时失败了 则这个key就永不过期了
}
}catch(Exception e){
logger.error("redis操作异常", e);
}
若redis操作失败 从数据库中查询已抽奖次数

if(count == null){ //访问redis失败 从数据库中取抽奖次数
drawCount = getDrawCountFromDb(mobile, today);
}else{
drawCount = count.intValue() - 1;
}
考虑到数据库异常 抽奖次数还得减一

try{
drawDbOper(); //抽奖数据库操作
}catch(Exception e){
redisService.decr(key); //抽奖数减一
}
考虑到之前可能redis incr也失败了, 于是还得判断是否存在该key

catch(Exception e){
String value = redisService.get(key);
if(value != null){
redisService.decr(key);
}
}
考虑到redis decr也有可能失败 还得捕捉异常

catch(Exception e){
try{
String value = redisService.get(key);
if(value != null){
redisService.decr(key);
}
}catch(Exception e){
logger.error("redis操作失败", e);
}
}
TODO: 若之前redis incr成功 现在decr失败了怎么办?

若之前redis incr失败了, 则从数据库查询抽奖次数, 等之后redis恢复了, 因redis中未保存用户抽奖次数值, 用户还能再抽3次, 于是还得修改代码

boolean isRedisIncrSuccessful = true; //记录redis incr是否成功
if(count == null){ //访问redis失败 从数据库中取抽奖次数
drawCount = getDrawCountFromDb(mobile, today);
isRedisIncrSuccessful = false;
}
try{
drawDbOper(); //抽奖数据库操作
//成功操作后 判断之前redis incr操作是否成功
if(!isRedisIncrSuccessful){// 若之前redis incr操作失败
// 补执行incr
redisService.incr(key); //TODO: 捕捉异常
}
}
引入了redis来防超抽后, 就好像娶错了人, 不得安生, 没完没了。

于是索性认为redis操作不会有异常, 数据库操作不会有异常, 这下代码清爽多了。

Long count = redisService.incr(key );
if(count > 3){
//提示抽奖次数已满
return result;
}
doBusiness();

关键字:抽奖

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部