ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

基于redisson实现分布式锁

2022-05-02 14:01:27  阅读:165  来源: 互联网

标签:基于 redisson return String lock redis private lockKey 分布式


  在日常业务开发中,为了解决并发问题,比如,同一个时刻,多笔相同订单号的订单同时请求,我们只会受理一笔,其他的请求拒绝。我们通常都是用分布锁来解决,当然,也可以使用数据库的唯一索引来解决,数据新增的时候会报插入异常,这样如果系统并发很大,会给数据库造成很大的压力,通常都不会这么操作。
  实现分布式锁的方案有很多种,比如用 zookeeper、redis等中间件,本文主要介绍使用 redission 实现分布锁,主要原因有以下几点:

  • 生产有redis 哨兵集群,不需要在部署其他中间件环境
  • redission 有看门狗机制,能自动给分布式锁延期(这个可以网上搜索参考其他文章)

一、环境说明

maven 依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.2.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson-spring-boot-starter</artifactId>
  <version>3.11.2</version>
</dependency>

二、代码实现

@Configuration
@Setter
@ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
public class RedisClientConfig {

  @Value("${redis.clusterName}")
    private String clusterName;

    @Value("${redis1.host}")
    private String redis1Host;

    @Value("${redis1.port}")
    private Integer redis1Port;

    @Value("${redis2.host}")
    private String redis2Host;

    @Value("${redis2.port}")
    private Integer redis2Port;


    @Value("${redis3.host}")
    private String redis3Host;

    @Value("${redis3.port}")
    private Integer redis3Port;

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSentinelServers()
                .setMasterName(clusterName)
                .addSentinelAddress("redis://"+redis1Host+":"+redis1Port)
                .addSentinelAddress("redis://"+redis2Host+":"+redis2Port)
                .addSentinelAddress("redis://"+redis3Host+":"+redis3Port);
        return Redisson.create(config);
    }

}
/**
 * redis 分布式锁
 */
@Component
@Slf4j
public class RedisLock {

    @Autowired
    private RedissonClient redissonClient;

    /**
     *  尝试拿锁 waitTime 后停止重试,返回false
     * @param lockKey 锁key值
     * @param unit  时间单位
     * @param waitTime  等待时间
     * @return 是否获取锁成功
     */
    public boolean tryLock(String lockKey, long waitTime,long leaseTime,TimeUnit unit) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime,leaseTime, unit);
        } catch (InterruptedException e) {
            log.error("获取redis分布式锁异常",e);
            return false;
        }
    }

    /**
     * 尝试拿锁,不重试,获取不到,返回false
     * 具有Watch Dog 自动延期机制 默认续30s
     * @param lockKey
     * @return
     */
    public boolean tryLock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(0L, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            log.error("获取redis分布式锁异常",e);
            return false;
        }
    }

    /**
     * 释放锁
     * @param lockKey
     */
    public void unlock(String lockKey) {
        try {
            RLock lock = redissonClient.getLock(lockKey);
            if(lock.isLocked()){
                lock.unlock();
            }
        } catch (Exception e) {
            log.error("释放锁异常",e);
        }
    }

}

标签:基于,redisson,return,String,lock,redis,private,lockKey,分布式
来源: https://www.cnblogs.com/wallacepang/p/16215679.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有