redis实现秒杀功能例子(采用lua的原子性保证数据的一致性)

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,(
// <task:executor id=“executor” pool-size=“5”/>
// <task:annotation-driven executor=“executor”/>)
// 再调用代理会帮我们实现异步
// goodsService.synDataBase(gid)
// 从redis中获得订单详情及卖出数量再批量插入
}
return Integer.parseInt(result.toString());
}
}

转载博客: https://blog.csdn.net/futao127/article/details/80617214

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值