Site Overlay

Redisson简单实现redis分布锁并封装

原理简而言之就是:如果有人正在修改某个reids,就上锁,存一个标记到redis中,修改完了就解锁,删除标记。

实现步骤:

导入Redisson依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-data-21</artifactId>
    <version>3.12.5</version>
</dependency>

新建redisson.yml

#Redisson配置
singleServerConfig:
  address: "redis://round003.miracle-cn.com:6379"
  password: CDmrk001
  clientName: demo02-redisson
  #选择使用哪个数据库0~15
  database: 0
  # 连接空闲超时,单位:毫秒
  idleConnectionTimeout: 10000
  # 连接超时,单位:毫秒
  connectTimeout: 10000
  # 命令等待超时,单位:毫秒
  timeout: 3000
  # 命令失败重试次数,如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。
  # 如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。
  retryAttempts: 3
  # 重新连接时间间隔,单位:毫秒
  retryInterval: 1500
  #reconnectionTimeout: 3000
  #  failedAttempts: 3
  subscriptionsPerConnection: 5
  # 发布和订阅连接的最小空闲连接数
  subscriptionConnectionMinimumIdleSize: 1
  # 发布和订阅连接池大小
  subscriptionConnectionPoolSize: 50
  # 最小空闲连接数
  connectionMinimumIdleSize: 32
  # 连接池大小
  connectionPoolSize: 64
  # DNS监测时间间隔,单位:毫秒
  dnsMonitoringInterval: 5000
  #dnsMonitoring: false

# 线程池数量,默认值: 当前处理核数量 * 2
threads: 0
# Netty线程池数量,默认值: 当前处理核数量 * 2
nettyThreads: 0
codec:
  class: "org.redisson.codec.JsonJacksonCodec"
  # 传输模式
transportMode: "NIO"

在RedisConfiguration中添加@bean

 @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient(@Value("classpath:/redisson.yml") Resource configFile) throws IOException {
        Config config = Config.fromYAML(configFile.getInputStream());
        log.info("address:{}",config.useSingleServer().getAddress());
        return Redisson.create(config);
    }

封装RedisLockUtil工具类

package com.miracle.pay.util;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import java.util.concurrent.TimeUnit;

/**
 * @Author Diuut
 * @Date 2020/5/13  13:52
 */
@Component
public class RedisLockUtil {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 加锁
     *
     * @param lockKey 锁Key
     * @return
     */
    public RLock lock(String lockKey) {

        RLock rlock = redissonClient.getLock(lockKey);
        rlock.lock();
        return rlock;
    }

    /**
     * 释放锁
     *
     * @param lockKey 锁Key
     */
    public void unlock(String lockKey) {
        RLock rlock = redissonClient.getLock(lockKey);
        rlock.unlock();
    }

    /**
     * 释放锁
     *
     * @param lock 锁对象
     */
    public static void unlock(RLock lock) {
        lock.unlock();
    }

    /**
     * 带超时的锁
     *
     * @param lockKey 锁key
     * @param timeout 超时时间   单位:秒
     */
    public RLock lock(String lockKey, int timeout) {
        RLock rLock = redissonClient.getLock(lockKey);
        rLock.lock(timeout, TimeUnit.SECONDS);
        return rLock;
    }

    /**
     * 带超时的锁
     *
     * @param lockKey 锁key
     * @param unit    时间单位
     * @param timeout 超时时间
     */
    public RLock lock(String lockKey, int timeout, TimeUnit unit) {
        RLock rLock = redissonClient.getLock(lockKey);
        rLock.lock(timeout, unit);
        return rLock;
    }

    /**
     * 尝试获取锁
     *
     * @param lockKey   锁key
     * @param waitTime  最多等待时间  单位:秒
     * @param leaseTime 上锁后自动释放锁时间  单位:秒
     * @return
     */
    public boolean tryLock(String lockKey, int waitTime, int leaseTime) throws InterruptedException {
        RLock lock = redissonClient.getLock(lockKey);
        return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
    }

    /**
     * 尝试获取锁
     *
     * @param lockKey   锁key
     * @param unit      时间单位
     * @param waitTime  最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) throws InterruptedException {
        RLock lock = redissonClient.getLock(lockKey);
        return lock.tryLock(waitTime, leaseTime, unit);
    }
}

以上就完成了就可以使用了。使用例子:

 public void saveUser(int userUid,User user){
        try {
            redisLockUtil.lock("userLock-uid:" + userUid);
            log.info("userLock-uid: " + userUid + "上锁");
            String userData = JSONObject.toJSONString(user);
            redisTemplate.opsForValue().set("user-uid:" + userUid, userData, 7, TimeUnit.DAYS);
            redisTemplate.opsForSet().add("redis-update-queue", "user-uid:"+userUid);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            redisLockUtil.unlock("userLock-uid:" + userUid);
            log.info("userLock-uid: " + 10135 + "解锁");
        }
    }

发表回复

您的电子邮箱地址不会被公开。

A beliving heart is your magic My heart
欢迎来到Diuut的个人博客,这里是我的一些零零碎碎的知识汇总,希望有能帮到你的内容。 | 蜀ICP备2021011635号-1 | Copyright © 2024 Diuut. All Rights Reserved.