业务
抽奖 每天每个用户只能抽
3
次
想用redis来防同一用户并发超抽 极简代码如下
count = redisService.incr(key);
if(count > 3){
//提示 抽奖次数已用完
return;
}
doBusiness();
完善代码
设置过期时间
Long count = redisService.incr(key );
if(count != null && count == 1){
//过期时间24小时
redisService.expire(key, 24*60*60);
}
捕捉redis操作异常
Long count = null;
try{
count = redisService.incr(key );
if(count != null && count == 1){
//过期时间24小时
redisService.expire(key, 24*60*60); //若执行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();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。