redis实现简单分布式锁
更新时间:2024年07月01日 11:46:44 作者:呱呱123#
这篇文章主要介绍了redis实现简单分布式锁,文中通过代码示例讲解的非常详细,需要的朋友可以参考下
1.redisTemplate实现简单分布式锁
@Autowired RedisTemplate redisTemplate; /** * redis分布式锁演示案例,此处使用redisTemplate * @param stockId 此处以扣减库存为例子,stockId代表要扣减库存的商品id,库存数据是提前存在redis的,并和数据库进行同步 * @return */ public AjaxResult redisLockDemo(String stockId){ //锁前缀 final String stock_lock = "stock_lock:"; // 生成一个随机唯一的值用于辨别锁的使用对象 String clientId = UUID.randomUUID().toString(); //此处使用set(k,v,time,unit)来获取锁,确保加锁和设置超时时间是原子操作 Boolean lock = redisTemplate.opsForValue().setIfAbsent(stock_lock + stockId, clientId, 10, TimeUnit.MILLISECONDS); if (!lock){ //获取锁失败 return AjaxResult.error("服务器繁忙,请稍后再试!"); } //获取锁成功 //执行扣减库存 try { int stock = (int) redisTemplate.opsForValue().get(stockId); if (stock > 0){ int realStock = stock - 1; // 重新设置库存数据 redisTemplate.opsForValue().set(stockId, realStock + ""); // .............其他步骤 log.info("库存扣减成功{}", stockId); } else { return AjaxResult.error("商品已经被抢光了!"); } } finally { //释放锁 // if (clientId.equals(stringRedisTemplate.opsForValue().get(stock_lock + stockId))){ // stringRedisTemplate.delete(stock_lock + stockId); // } //此处使用lua脚本释放锁,具有原子性 String script = "local lockKey = KEYS[1]\n" + "local clientId = ARGV[1]\n" + "local currentHolder = redis.call('GET', lockKey)\n" + "if currentHolder == clientId then\n" + " redis.call('DEL', lockKey)\n" + " return true\n" + "else\n" + " return false\n" + "end"; DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(script, Boolean.class); Boolean result = (Boolean) redisTemplate.execute(redisScript, Collections.singletonList(stock_lock + stockId), clientId); if (result != null && result) { log.info("所释放成功"); } else { log.info("所释放失败"); } } return AjaxResult.success("扣减库存成功!"); }
2.redission实现分布式锁
@Autowired Redisson redisson; /** * redis分布式锁演示案例,redisson * @param stockId 此处以扣减库存为例子,stockId代表要扣减库存的商品id,库存数据是提前存在redis的,并和数据库进行同步 * @return */ public AjaxResult redissonLockDemo(String stockId){ final String lockKey = "stock_lock:"; RLock lock = redisson.getLock(lockKey); lock.lock(); try { //执行扣减库存 int stock = (int) redisTemplate.opsForValue().get(stockId); if (stock > 0){ int realStock = stock - 1; // 重新设置库存数据 redisTemplate.opsForValue().set(stockId, realStock + ""); // .............其他步骤 log.info("库存扣减成功{}", stockId); } else { return AjaxResult.error("商品已经被抢光了!"); } }finally { lock.unlock(); } return AjaxResult.success("扣减库存成功!"); }
以上就是redis实现简单分布式锁的详细内容,更多关于redis分布式锁的资料请关注脚本之家其它相关文章!
相关文章
websocket+redis动态订阅和动态取消订阅的实现示例
本文主要介绍了websocket+redis动态订阅和动态取消订阅,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2022-05-05
最新评论