前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Redisson简单实现redis分布锁并封装

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

作者头像
Diuut
发布2022-11-22 20:06:43
发布2022-11-22 20:06:43
56100
代码可运行
举报
文章被收录于专栏:DiuutDiuut
运行总次数:0
代码可运行

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

实现步骤:

导入Redisson依赖

代码语言:javascript
代码运行次数:0
运行
复制
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-data-21</artifactId>
    <version>3.12.5</version>
</dependency>

新建redisson.yml

代码语言:javascript
代码运行次数:0
运行
复制
#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

代码语言:javascript
代码运行次数:0
运行
复制
 @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工具类

代码语言:javascript
代码运行次数:0
运行
复制
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);
    }
}

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

代码语言:javascript
代码运行次数:0
运行
复制
 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 + "解锁");
        }
    }

Post Views: 215

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020年5月15日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档