springboot集成分布式锁redissonLock

引入依赖

  <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.68</version>
  </dependency>
  <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>log4j-over-slf4j</artifactId>
  </dependency>
  <dependency>
      <groupId>org.redisson</groupId>
      <artifactId>redisson</artifactId>
      <version>3.14.0</version>
  </dependency>

RedissonConfig

创建连接

@Configuration
public class RedissionConfig {
    @Bean
    public RedissonClient getRedisson() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        return Redisson.create(config);
    }
}

RedissonUtil

@Component
public class RedissonUtil {

	@Autowired
	private RedissonClient redissonClient;

	private Logger logger = Logger.getLogger(RedissonUtil.class);

	private final String LOCK_FLAG = "rlock_";

    /**
     * 根据name对进行上锁操作,redissonLock 阻塞事的,采用的机制发布/订阅
     * @param lockName
     */
    public void lock(String lockName, int timeOutMinute) {
        String key = LOCK_FLAG + lockName;
        RLock lock = redissonClient.getLock(key);
        //lock提供带timeout参数,timeout结束强制解锁,防止死锁 :1分钟
        lock.lock(timeOutMinute, TimeUnit.MINUTES);
    }
    
    /**
     * 根据name对进行上锁操作,redissonLock 阻塞事的,采用的机制发布/订阅
     * @param lockName
     */
    public void lock(String lockName) {
        String key = LOCK_FLAG + lockName;
        RLock lock = redissonClient.getLock(key);
        lock.lock();
    }

	/**
	 * 根据name进行上锁操作,redissonLock 非阻塞的
	 *
	 * @param lockName
	 * @param waitTime 毫秒,等待锁的时间,等待超时即放弃
	 * @return true锁成功,false锁失败
	 */
	public boolean trylock(String lockName, long waitTime) {
		try {
			String key = LOCK_FLAG + lockName;
			RLock lock = redissonClient.getLock(key);
			return lock.tryLock(waitTime, TimeUnit.MILLISECONDS);
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 多重锁<br>
	 * 根据name进行上锁操作,redissonLock 非阻塞的
	 *
	 * @param lockNamePre 锁前缀
	 * @param waitTime 毫秒,等待锁的时间,等待超时即放弃
	 * @param args        锁后缀列表
	 * @return true锁成功,false锁失败
	 */
	public boolean trylock(String lockNamePre, List<String> args, long waitTime) {
		boolean flag;
		RLock[] locks = new RLock[args.size()];
		for (int i=0;i<args.size();i++) {
			String key = LOCK_FLAG + lockNamePre + args.get(i);
			RLock lock = redissonClient.getLock(key);
			locks[i] = lock;
		}
		RLock multiLock = redissonClient.getMultiLock(locks);
		try {
			flag = multiLock.tryLock(waitTime, TimeUnit.MILLISECONDS);
		} catch (Exception e) {
			flag = false;
		}
		return flag;
	}

	/**
	 * 根据name进行解锁操作
	 *
	 * @param lockNamePre 锁前缀
	 * @param args        锁后缀列表
	 */
	public void unlock(String lockNamePre, List<String> args) {
		RLock[] locks = new RLock[args.size()];
		for (int i=0;i<args.size();i++) {
			String key = LOCK_FLAG + lockNamePre + args.get(i);
			RLock lock = redissonClient.getLock(key);
			locks[i] = lock;
		}
		RLock multiLock = redissonClient.getMultiLock(locks);
		multiLock.unlock();
	}

    /**
     * 根据name对进行解锁操作
     * @param lockName
     */
    public void unlock(String lockName) {
        String key = LOCK_FLAG + lockName;
        RLock lock = redissonClient.getLock(key);
        lock.unlock();
    }

}

使用分布式锁

@Service
public class StockFlowServiceImpl extends ServiceImpl<StockFlowMapper, SkillStockFlow> implements StockFlowService {
    @Autowired
    private ActivityItemServiceImpl activityItemService;
    @Autowired
    private RedissonUtil redissonUtil;
    @Override
    public boolean skillItem(SkillDto skillDto) {
        boolean trylock = false;
        String orderId = UUID.randomUUID().toString().replace("-","");
        //lockName不一样,持的锁就不一样
        String lockName = skillDto.getItemId();

        try {
            trylock = redissonUtil.trylock(lockName,100);
            if (!trylock){
                return false;
            }
            boolean flag = activityItemService.reduceStock(skillDto.getItemId(), skillDto.getBuyNum());
            if (flag){
                SkillStockFlow skillStockFlow = new SkillStockFlow();
                BeanUtils.copyProperties(skillDto,skillStockFlow);
                skillStockFlow.setOrderId(orderId);
                save(skillStockFlow);
            }
            return true;
        } catch (BeansException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (trylock){
                redissonUtil.unlock(lockName);
            }
        }
    }
}

参考博客:
Redisson重连后WatchDog失效问题解决http://events.jianshu.io/p/84522c2736a2

获取锁的原理参考博客:https://blog.csdn.net/qq_41489540/article/details/113772408

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值