redis乐观锁、事务、分布式锁的实现

粗茶淡饭 2020-05-10

配置,需要设置setEnableTransactionSupport,开启事务

@Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setEnableTransactionSupport(true);//开启支持事务 multi exec
        return template;
    }

实现理念

/**
     * redis 乐观锁 + 事务 的实现
     */
    @Test
    public void lockDemo1() {

        try {
            redisTemplate.watch("name");

            redisTemplate.multi();

            //进行事务代码
            // .....
            // .....
            // .....

            //最后提交事务
            List<Object> exec = redisTemplate.exec();

            if (exec.isEmpty()) {
                System.out.println("操作失败");
            }

        } catch (RuntimeException e) {

            //出现异常撤销
            redisTemplate.discard();

        } finally {
            redisTemplate.unwatch();
        }
    }

使用 setnx(set if not exist)实现分布式锁

setnx性质:如果不存在那么返回 0 ,不存在返回 1 。

/**
     * redis 使用setnx命令实现分布式锁
     */
    @Test
    public void lockDemo() {

        Supplier<Boolean> getLock = () -> {
            Boolean b = redisTemplate.opsForValue().setIfAbsent("lock-name", "lock-val");
            return b != null && b;
        };

        try {

            //循环获取分布式锁
            while (!getLock.get()) ;

            //进行的业务代码
            synchronized (RedisTest.class) {
                //.....
            }

        } finally {
            //防止异常,释放锁
            redisTemplate.delete("lock-name");
        }

    }

相关推荐

DiamondTao / 0评论 2020-08-30