0
点赞
收藏
分享

微信扫一扫

Redissons实现分布式锁

香小蕉 2021-09-19 阅读 66
杨文来

1.添加pom和配置文件

        <!--redisson-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.11.6</version>
        </dependency>
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Autowired
    private AppConfig appConfig;

    /**
     * 配置redisTemplate实例
     * @return
     */
    @Bean
    RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        // 设置值(value)的序列化采用Jackson2JsonRedisSerializer。
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // 设置键(key)的序列化采用StringRedisSerializer。
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

  /**
     * 配置RdeissonClint实例
     * @return
     */
    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        config.useSingleServer().setAddress("redis://" + "127.0.0.1" + ":" + "6379");
        if (StringUtils.isNotBlank(appConfig.getPassword())){
            config.useSingleServer().setPassword(appConfig.getPassword());
        }
        return Redisson.create(config);
    }

2.使用方法

    @Autowired
    private RedissonClient redissonClient;

    @GetMapping("seckill")
    public Integer test() throws InterruptedException {
        // 获取锁对象
        RLock lock = redissonClient.getLock("lock");
        try {
            // 参数一:尝试加锁等待时间
            // 参数二:锁key生存时间
            // 参数三:时间单位
            if (lock.tryLock(0,10, TimeUnit.SECONDS)) {
                //  加锁成功,Do something
            }else {
                // 加锁失败
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            // 释放锁
            lock.unlock();
        }
        return null;
    }

lock和tryLock的区别:
lock:加锁,会阻塞线程
tryLock:尝试加锁,不会阻塞线程,返回值是boolean值,建议使用

使用Redisson的好处

相较于setnx,都可以实现分布式锁,但是redisson更加强大
setnx设置的锁过期时间不合理,且任务执行时间较长的时候会导致锁被释放了,肯定是有问题的。
解决办法:开启一个守护线程,监控任务执行时间,如果时间过长则延长锁的过期时间,这个开发代价会很大。
redisson已经很好的锁过期时间的问题,内部使用了设计模式之观察者模式,监控任务执行时间和锁过期时间,如果锁快到时间了任务还没执行完,就会帮我们增加锁过期时间,是个很强大的框架。

举报

相关推荐

0 条评论