分布式锁“失效“问题

背景:同事开发一个扫码活动。需要处理并发扫一个码的问题。采用redison分布式锁处理。锁生效了,但是并发扫码没控制住。

我推荐他使用:

1 乐观锁

2 处理扫码业务代码块 提炼成方法,这个方法加上事务。而不是把分布式锁放在事务里面。

 @Transactional(rollbackFor = Exception.class)
    public ScanQrCodeResultVO execScanQrCode(...){
         // 校验
        // 业务代码加锁
        RLock lock = redissonClient.getSpinLock("key");
    try {
        //判断是否被扫
        //扫码发放奖励
    }  catch (Exception e) {
           //
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
}

修改成

    public ScanQrCodeResultVO execScanQrCode(...){
         // 校验
        // 业务代码加锁
        RLock lock = redissonClient.getSpinLock("key");
    try {
        
    }  catch (Exception e) {
           handleScanCode(...)
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
     @Transactional(rollbackFor = Exception.class)
     public void handleScanCode(...){
    //判断是否被扫
    //扫码发放奖励
    
    }

后面排查到:

因为finally里面添加了解锁,而解锁后才会提交事务。导致后一个扫码查询不到前一个扫码的数据变更。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分布式锁失效时,可能会导致多个节点同时访问共享资源,引发并发冲突问题。为了解决这个问题,可以考虑以下几种方法: 1. 设置锁的过期时间:在获取锁时,为锁设置一个合理的过期时间。当锁的持有者在一定时间内没有释放锁,锁会自动过期。其他节点可以在锁过期后重新竞争获取锁。但是要注意设置合理的过期时间,避免因为过长的锁持有时间导致系统性能下降。 2. 使用带有守护线程的锁:在获取锁时,创建一个守护线程用于定时续约锁的过期时间。守护线程周期性地更新锁的过期时间,确保持有锁的节点在正常情况下不会因为长时间未释放锁而导致锁失效。 3. 引入分布式协调服务:使用分布式协调服务如ZooKeeper或etcd来实现分布式锁。这些服务提供了原子性操作和顺序性保证,可以确保只有一个节点能够成功获取到锁。当持有锁的节点异常退出或者释放锁时,其他节点可以通过监听事件来重新竞争获取锁。 4. 优化资源访问逻辑:对于某些场景,可以考虑优化资源的访问逻辑,减少对分布式锁的依赖。例如,利用乐观锁或者悲观锁来减少对共享资源的并发访问,或者通过分片或分段等方式将共享资源划分为多个小块,降低并发冲突的概率。 无论采用哪种方法,都需要根据具体的业务场景和系统架构做出合理的选择,并进行充分的测试和评估,确保解决分布式锁失效问题的方案可靠性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值