Redission分布式锁快速入门

Redisson简介

Redisson是一个用户Redis的Java客户端,可以让Java应用中使用Redis更加容易和直观。简化

Redis的基本操作,还提供了丰富的功能,比如:分布式锁、信号量、闭锁的高级特性。

Redisson分布式锁的作用

想象一个连锁超市的仓库管理系统,问题出在这里:

  1. 单店保安(synchronized)的问题
    每个分店都雇了一个保安(JVM锁),只能管自己仓库的货物。
    问题场景:如果北京和上海分店同时抢着调拨全国最后一台电视,两个保安都认为"我这的电视可以卖",导致超卖。

  2. 总部调度系统(Redisson分布式锁)​
    总部给所有分店配了一个智能手环(Redisson),通过中央对讲机(Redis)协调:

    • 当任意分店要操作电视库存时,必须先喊:"总部,我要锁电视!"
    • 如果总部回应:"锁成功",只有这个分店能操作,其他分店必须排队等待。
    • 操作完成后必须喊:"总部,我释放电视锁!"(避免死锁)。

Redisson使用场景

场景1:多人同时下单可能导致库存扣减冲突,出现负库存问题。例如,用户A和用户B同时查询到

某商品库存为1,均下单成功但实际库存不足。

场景2:用户重复提交订单或支付回调并发处理时,可能生成重复订单或重复扣款。

场景3:定时任务(如每日库存同步、优惠券过期处理)在集群中多节点运行时,需避免重复执

行。

SpringBoot使用Redisson

导入依赖

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

配置Redis连接信息

spring:
  data:
    redis:
      port: 6379
      host: 127.0.0.1
#      password: 123456
      database: 0

# Redisson专属配置(可选)
redisson:
  singleServerConfig:
    connectionPoolSize: 10       # 最大连接数
    idleConnectionTimeout: 10000  # 空闲超时(ms)
    connectTimeout: 5000         # 连接超时(ms)

配置Redisson客户端

@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://localhost:6379")
                .setDatabase(0);
        return Redisson.create(config);
    }
}

编写测试案例

@RestController
public class RedissonDemoController {

    @Autowired
    private RedissonClient redissonClient;

    // 分布式锁示例
    @GetMapping("/lock")
    public void testLock() {
        //会在redis中添加一个Map数据类型,Map的key是myLock
        RLock lock = redissonClient.getLock("myLock");
        try {
            // 尝试加锁,等待时间为10秒,过期时间为30秒
            boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
            if (isLocked) {
                // 成功获取到锁,执行业务逻辑
                System.out.println("获取锁成功,即将执行业务逻辑...");
                Thread.sleep(30*1000);
            } else {
                // 加锁失败
                System.out.println("获取锁失败,请稍后再试");
            }
        } catch (InterruptedException e) {
            // 处理异常
        } finally {
            lock.unlock();
            System.out.println("释放锁成功");
        }
    }
}

锁说明

boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
  • 10:表示尝试获取锁的操作将在最多10秒内处于等待状态尝试获取锁。如果在这10秒内锁变为可用(即当前没有其他客户端持有该锁),则此方法会成功获取锁并返回true
  • 30:表示锁的最大保持时间是30秒。也就是说,即使获取到了锁,如果在30秒内没有主动释放锁(调用unlock方法),锁也会自动释放,防止死锁的发生。
  • TimeUnit.SECONDS:指定上述两个参数的时间单位为秒。

如果锁的最大保持时间是-1,那么就会启用看门狗机制,每10秒自动续期锁的时间。

Redisson中的看门狗机制(Watchdog机制)用于自动续期分布式锁的有效期。当你使用Redisson

获取一个分布式锁但没有明确设置锁的过期时间(或者设置了特殊的值如-1),看门狗机制会自动

启动,并且在后台定期延长锁的过期时间。

默认情况下,如果一个锁被成功获取并且没有设定过期时间,Redisson的看门狗会每10秒检查一

次锁的状态,并将锁的有效期重置为30秒(这个时间可以通过配置进行调整)。这意味着,只要持

有锁的线程仍在运行并且没有主动释放锁,锁就会一直保持有效状态。

这种机制特别有用,因为在分布式系统中,有时很难准确预估完成临界区代码所需的时间。如果没

有看门狗机制,可能会因为预设的锁过期时间过短而导致锁提前释放,进而引发并发问题。而有了

看门狗机制,即使处理时间超过预期,只要任务还在执行,锁就不会过期,从而避免了这种情况的

发生。

但是需要注意的是,如果业务逻辑已经完成了对共享资源的操作,应该及时调用unlock()方法来手

动释放锁,以便其他等待的线程可以获取锁并继续执行。否则,看门狗会持续续期锁,可能导致锁

长时间被占用的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陶然同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值