Redisson 分布式锁出现死锁,两种解决方式

在多节点应用中,使用Redisson3.10.1实现分布式锁以防止单号重复。当应用获取锁后宕机,看门狗未能按预期超时解锁导致死锁。解决方法包括直接删除数据库中的锁键或通过Java脚本执行lock.delete()来解除锁。
摘要由CSDN通过智能技术生成

项目场景:

多节点应用获取单号,使用Redisson(3.10.1)分布式锁保证单号不会重复。


问题描述

有一台应用已经获取到分布式锁,还没解锁就突然宕机,虽然看门狗默认设置internalLockLeaseTime/lockWatchdogTimeout = 30000毫秒,正常情况会超时解锁,但没有生效(原因不明),此时出现死锁。

public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://127.0.0.1:6372")
                .setPassword("123456")
                .setDatabase(5)
                .setConnectTimeout(10000)
                .setTimeout(10000)
                .setPingConnectionInterval(3000);
        RedissonClient redissonClient = Redisson.create(config);

        System.out.println("=================================================");
        test(redissonClient, false);
//      redissonClient.shutdown();
    }

    private static void test(RedissonClient redissonClient, Boolean flag) {
        // 分布式锁
        RLock lock = redissonClient.getLock("BILL_NO:AAA");
        System.out.println("1、开始 " + lock.getName());
        Boolean isDead = true;
        try {
            if (lock.tryLock(5, TimeUnit.SECONDS)) {
                System.out.println("2、执行业务 " + lock.getName());
                isDead = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (flag && lock.isLocked() && lock.isHeldByCurrentThread()) {
                System.out.println("3、解锁 " + lock.getName());
                lock.unlock();
            } else {
                System.out.println("3、不解锁 " + lock.getName());
            }
            System.out.println("4、结束 " + lock.getName());
//            if (isDead) {
//            System.out.println("kill lock " + lock.getName());
//                lock.delete();
//            }
        }
    }
======================================================================================
1、开始 BILL_NO:AAA
2、执行业务 BILL_NO:AAA
3、不解锁 BILL_NO:AAA
4、结束 BILL_NO:AAA

在这里插入图片描述


解决方案:

  一般情况只有应用线程持有这把锁,才会通过看门狗续期,默认30s会过期回收。无法回收的情况下,说明没有设置超期时间,可以以下处理:
 1、redisson会在db-5创建分布式锁key,可以直接删除key。
 2、使用java脚本,执行 lock.delete()。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值