秒杀的大概思路:
- 首先进入秒杀页面初始化方法从redis缓存中查找秒杀商品,如果缓存中有,那就从缓存中提取数据,如果没有,就按照条件(当前时间是否和秒杀开始和结束时间符合)从数据库中查找所有秒杀商品信息并且存储到缓存中。
- 用户点击查看某个商品进入详情页面的时候,从缓存中读取该商品的详细信息,其中有一个难点是前端的倒计时显示,下文的代码展示会写。
- 用户点击购买,先判断是否登录,如果没登录,则提示用户进行登录,如果已经登录,则开始购买,在redis中创建订单列,以用户账号作为key值存储进去,要注意判断当前商品库存是否还有,可以开启redis的事务管理来防止高并发的情况,同时更新缓存中的商品库存信息。
- 用户支付后,会将redis中的订单信息存储到数据库订单表,同时删除掉redis的缓存,并且更新缓存中的商品信息,同时修改数据库中的商品数量。
下面一一进行代码展示(以笔者的demo为例)
1.秒杀商品展示,service实现层:
SecKillGoodsservice:
public List<TbSeckillGoods> findAll() {
List<TbSeckillGoods> seckillGoods =
(List<TbSeckillGoods>) redisTemplate.boundHashOps("seckillGoods").values();
if(seckillGoods==null||seckillGoods.size()==0){
//通过三个条件查询数据库 放入缓存
TbSeckillGoodsExample example = new TbSeckillGoodsExample();
Criteria criteria = example.createCriteria();
criteria.andStatusEqualTo("1");
criteria.andStartTimeLessThan(new Date());
criteria.andEndTimeGreaterThan(new Date());
criteria.andStockCountGreaterThan(0);
seckillGoods=seckillGoodsMapper.selectByExample(example);
for (TbSeckillGoods seckillGood : seckillGoods) {
//将得到的商品数据存入缓存中 使用id作为key 对象作为value
redisTemplate.boundHashOps("seckillGoods").put(seckillGood.getId()+"",seckillGood);
}
}
return seckillGoods;
}
2.商品详情页:
service实现层:
//controller层得到当前登录id
public TbSeckillGoods findOne(Long id) {
//从缓存中独居
return (TbSeckillGoods)redisTemplate.boundHashOps("seckillGoods").get(id+"");