import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
@Service
public class RedisServiceImpl {
@Autowired
private RedisTemplate template;
//lua脚本
private String script = "local number = ARGV[1] \n" +
"local gsave = redis.call('hget','goods_'..KEYS[1],'gsave') \n" +
"if gsave < number then \n" +
"return 2 \n" +
"end\n" +
"gsave = gsave - number \n" +
"redis.call('hset','goods_'..KEYS[1],'gsave',gsave)\n" +
"redis.call('rpush','orders_'..KEYS[1],ARGV[2])\n" +
"if gsave <= 0 then\n" +
"return 0\n"+
"else \n" +
"return 1\n" +
"end";
private String sha1 = null;
//lua脚本-原子性保证了数据的一致性
public int miaosha(Integer gid, Integer number, Integer uid){
Jedis jedis = (Jedis)template.getConnectionFactory().getConnection().getNativeConnection();
//加载脚本
if(sha1 == null){
sha1 = jedis.scriptLoad(script);
}
//执行脚本
String orderinfo = uid + "-" +number + "-" +System.currentTimeMillis();//订单信息
Long result = (Long)jedis.evalsha(sha1, 1,gid+"",number+"",orderinfo);
//抢购结束
if(result == 0){
// 异步去执行插入数据库的方法
// 注入IGoodsService,(<!--
// 配置这个后在方法前加注解@Async该方法就会变成异步的方法
// -->
// <task:executor id="executor" pool-size="5"/>
// <task:annotation-driven executor="executor"/>)
// 再调用代理会帮我们实现异步
// goodsService.synDataBase(gid)
// 从redis中获得订单详情及卖出数量再批量插入
}
return Integer.parseInt(result.toString());
}
}
redis实现秒杀功能例子(采用lua的原子性保证数据的一致性)
最新推荐文章于 2024-08-17 07:00:00 发布