springboot集成redis实现简单秒杀系统
本文实例为大家分享了springboot集成redis实现简单秒杀系统的具体代码,供大家参考,具体内容如下
项目是有地址的,我会放到文章的最后面
1.直接service,我们会介绍两种秒杀模式
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"; DefaultRedisScriptre=newDefaultRedisScript (); //设置脚本 re.setScriptText(luaScript); //定义返回值类型,注意,如果没有这个定义,Spring不会返回结果 re.setResultType(String.class); RedisSerializer stringRedisSerializer=stringRedisTemplate.getStringSerializer(); //执行LUA脚本 Stringresult=(String)stringRedisTemplate.execute(re,stringRedisSerializer,stringRedisSerializer,null); returnLong.valueOf(result); } @Override publicLongflashSellByRedisWatch(StringskuCode,intnum){ SessionCallback sessionCallback=newSessionCallback (){ @Override publicLongexecute(RedisOperationsoperations)throwsDataAccessException{ intresult=num; //redis乐观锁 //我们观察商品编码是否发生改变 operations.watch(skuCode); ValueOperations 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并发访问了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。