redis分布式锁的 实现

4 篇文章 0 订阅
1 篇文章 0 订阅

添加依赖
在这里插入图片描述
配置文件application.yml
db:
redis:
url: 地址
password: 密码

创建分布式锁类

package com.juseerp.business.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/**

  • redis 分布式锁

  • @Auther: zhouyc

  • @Date: 2022/3/4
    */
    @Component
    @Slf4j
    public class RedisLockUtil {

    @Autowired
    private RedisTemplate redisTemplate;
    /**

    • 加锁,自旋重试三次
    • @return
      */
      public boolean lock(String lockKey,String requestId) {
      boolean locked = false;
      int tryCount = 3;
      while (!locked && tryCount > 0) {
      locked = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, 3, TimeUnit.MINUTES);
      tryCount–;
      try {
      Thread.sleep(300);
      } catch (InterruptedException e) {
      log.error(“线程被中断” + Thread.currentThread().getId(), e);
      Thread.currentThread().interrupt();
      }
      }
      return locked;
      }

    /**

    • 非原子解锁,可能解别人锁,不安全
    • @return
      */
      public boolean unlock(String lockKey,String requestId) {
      boolean releaseLock = false;
      String oldRequestId = (String) redisTemplate.opsForValue().get(lockKey);
      if (requestId.equals(oldRequestId)) {
      releaseLock = redisTemplate.delete(lockKey);
      }
      return releaseLock;
      }

    /**

    • 使用lua脚本解锁,不会解除别人锁
    • @return
      */
      public boolean unlockLua(String lockKey,String requestId) {
      DefaultRedisScript redisScript = new DefaultRedisScript();
      //用于解锁的lua脚本位置
      redisScript.setLocation(new ClassPathResource(“unlock.lua”));
      redisScript.setResultType(Long.class);
      //没有指定序列化方式,默认使用上面配置的
      Object result = redisTemplate.execute(redisScript, Arrays.asList(lockKey), requestId);
      return result.equals(Long.valueOf(1));
      }
      }

实现锁:
public void lockStock() {
String redisKey = BusinessConstant.LOCK_PRODUCT_STOCK_PRE_KEY + temp.getStockId();
String val = UUIDUtil.getUUID();
try {
if (redisLockUtil.lock(redisKey, val)) {
需要执行方法
} else {
throw new GlobleException(String.format(“库存: %s锁定失败”, storeId)); }
} finally {
redisLockUtil.unlockLua(redisKey, val);
}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值