Redis分布式锁

该博客介绍了如何在SpringBoot项目中实现分布式并发控制,通过引入Redis并利用其setIfAbsent命令来实现分布式锁。文章强调了在分布式环境下保证操作原子性的重要性,并提醒注意设置超时时间和避免死锁。示例代码展示了如何创建和释放Redis锁,以确保在同一时刻只有一个进程能够执行特定操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:新工作的第一个需求要实现分布式的并发控制,跟以往写过的单服务应用不同,synchronized 锁sempheore信号量这种jvm层级的锁就不能满足要求了,要考虑类似阿里开源组件sentinel或者自己实现一个。

要实现分布式下的原子性,就要保证进程在操作竞态资源的时候是唯一的,不能出现并发的情况

redis锁可以满足这种要求,应用之间,能同时拿到redis锁的服务只能有一个,可以保证分布式下某个操作的原子性

对于springboot项目,首先引入redis依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

增加redis配置,这里redis是安装在本机的,全部都是默认配置

  redis:
    database: 0
    # Redis服务器地址
    host: localhost
    # Redis服务器连接端口
    port: 6379
    # Redis服务器连接密码(默认为空)
    password:
    # 链接超时时间 单位 ms(毫秒)
    timeout: 3000

最后是代码层面,主要原理就是使用redis的setIfAbsent命令实现锁的效果,示例代码如下

import java.util.concurrent.TimeUnit;

@Service
public class LockService {
    private static final String lockKey = "lockkey";
    private static final String lockValue = "lockvalue";

    @Autowired
    private RedisTemplate redisTemplate;
    //获取锁方法
    public boolean acquireRedisLock() {
        return redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 10, TimeUnit.SECONDS);
    }
    //释放锁方法
    public void releaseRedisLock() {
        if (lockValue.equals(redisTemplate.opsForValue().get(lockKey))) {
            redisTemplate.delete(lockKey);
        }
    }


}

任何应用,在操作资源之前先获取锁,另一进程尝获取锁时会执行setIfAbsent,此时锁value已经不为空了,所以执行会失败,在锁被释放之前都无法获取

注意点:

超时时间必须设置,且要根据具体业务时间长短来,如果有进程获取锁后宕机而又没有设置过期时间,会产生死锁。如果锁过期时间短于业务时间可能导致锁被提前释放导致错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值