springboot集成redis实现简单秒杀系统的方法

这篇文章给大家分享的是有关springboot集成redis实现简单秒杀系统的方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

1. 直接service,我们会介绍两种秒杀模式

springboot集成redis实现简单秒杀系统的方法

publicinterfaceGoodsService{

/**
*通过lua脚本实现的秒杀
*@paramskuCode商品编码
*@parambuyNum购买数量
*@return购买数量
*/
LongflashSellByLuaScript(StringskuCode,intbuyNum);
/**
*通过redis事务实现的秒杀
*@paramskuCode商品编码
*@parambuyNum购买数量
*@return购买数量
*/
LongflashSellByRedisWatch(StringskuCode,intbuyNum);

}

2. service实现类

importorg.springframework.dao.DataAccessException;
importorg.springframework.data.redis.core.RedisOperations;
importorg.springframework.data.redis.core.SessionCallback;
importorg.springframework.data.redis.core.StringRedisTemplate;
importorg.springframework.data.redis.core.ValueOperations;
importorg.springframework.data.redis.core.script.DefaultRedisScript;
importorg.springframework.data.redis.serializer.RedisSerializer;
importorg.springframework.stereotype.Service;

importjavax.annotation.Resource;
importjava.util.Collections;
importjava.util.List;

@Service
publicclassGoodsServiceImplimplementsGoodsService{

@Resource
privateStringRedisTemplatestringRedisTemplate;

@Override
publicLongflashSellByLuaScript(StringskuCode,intnum){
//下面是lua脚本
StringluaScript="localbuyNum=ARGV[1]\n"+
"localgoodsKey=KEYS[1]\n"+
"localgoodsNum=redis.call('get',goodsKey)\n"+
"ifgoodsNum>=buyNum\n"+
"thenredis.call('decrby',goodsKey,buyNum)\n"+
"returnbuyNum\n"+
"else\n"+
"return'0'\n"+
"end\n"+
"\n";

DefaultRedisScript<String>re=newDefaultRedisScript<String>();
//设置脚本
re.setScriptText(luaScript);
//定义返回值类型,注意,如果没有这个定义,Spring不会返回结果
re.setResultType(String.class);
RedisSerializer<String>stringRedisSerializer=stringRedisTemplate.getStringSerializer();
//执行LUA脚本
Stringresult=(String)stringRedisTemplate.execute(re,stringRedisSerializer,stringRedisSerializer,null);
returnLong.valueOf(result);
}

@Override
publicLongflashSellByRedisWatch(StringskuCode,intnum){

SessionCallback<Long>sessionCallback=newSessionCallback<Long>(){
@Override
publicLongexecute(RedisOperationsoperations)throwsDataAccessException{
intresult=num;
//redis乐观锁
//我们观察商品编码是否发生改变
operations.watch(skuCode);
ValueOperations<String,String>valueOperations=operations.opsForValue();
StringgoodsNumStr=valueOperations.get(skuCode);
IntegergoodsNum=Integer.valueOf(goodsNumStr);
//标记一个事务块的开始。
//事务块内的多条命令会按照先后顺序被放进一个队列当中,
//最后由EXEC命令原子性(atomic)地执行。
operations.multi();
if(goodsNum>=num){
valueOperations.increment(skuCode,0-num);
}else{
result=0;
}
//多条命令执行的结果集合
Listexec=operations.exec();
if(exec.size()>0){
System.out.println(exec);
}
return(long)result;
}
};
returnstringRedisTemplate.execute(sessionCallback);
}
//省略其他的方法


}

3. controller

但是首先要向你的redis里面仍一个数据,key='xiaomi',value='100'

@ApiOperation(value="用事务秒杀测试接口",notes="用事务秒杀测试接口")
@RequestMapping(value="/miaoTransaction",method=RequestMethod.GET)
@ResponseBody
publicLongmiaoTransaction(){

Longres=goodsService.flashSellByRedisWatch("xiaomi",1);
returnres;
}


@ApiOperation(value="秒杀Lua测试接口",notes="秒杀Lua测试接口")
@RequestMapping(value="/miaoLua",method=RequestMethod.GET)
@ResponseBody
publicLongmiaoLua(){

Longres=goodsService.flashSellByRedisWatch("xiaomi",1);
System.out.println(res.toString());
returnres;
}

然后就可以用jemeter并发访问了。

感谢各位的阅读!关于“springboot集成redis实现简单秒杀系统的方法”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

发布于 2021-05-30 14:09:54
收藏
分享
海报
0 条评论
178
上一篇:Qt自定义控件如何实现进度仪表盘 下一篇:Composer如何实现自动加载原理
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码