Spring Boot + RedisTemplate实现分布式锁

Spring Boot + RedisTemplate实现

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class RedisTemplateDistributedLock {
    private StringRedisTemplate redisTemplate;
    private String lockKey;
    private String lockValue;
    private int expireTime; // 毫秒
    
    public RedisTemplateDistributedLock(StringRedisTemplate redisTemplate, 
                                      String lockKey, int expireTime) {
        this.redisTemplate = redisTemplate;
        this.lockKey = lockKey;
        this.expireTime = expireTime;
        this.lockValue = UUID.randomUUID().toString();
    }
    
    public boolean tryLock(long waitTime) throws InterruptedException {
        long start = System.currentTimeMillis();
        
        while (true) {
            Boolean acquired = redisTemplate.opsForValue().setIfAbsent(
                lockKey, lockValue, expireTime, TimeUnit.MILLISECONDS);
            
            if (Boolean.TRUE.equals(acquired)) {
                return true;
            }
            
            if (System.currentTimeMillis() - start >= waitTime) {
                return false;
            }
            
            Thread.sleep(100);
        }
    }
    
    public void unlock() {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                       "return redis.call('del', KEYS[1]) " +
                       "else " +
                       "return 0 " +
                       "end";
        
        redisTemplate.execute(
            new DefaultRedisScript<>(script, Long.class),
            Collections.singletonList(lockKey),
            lockValue
        );
    }
}

分布式锁的最佳实践

  1. 设置合理的过期时间:确保锁能够自动释放,防止死锁

  2. 使用唯一标识:确保只有锁的持有者才能释放锁

  3. 避免长时间持有锁:锁的持有时间应尽可能短

  4. 考虑锁的可重入性:如果需要可重入锁,可以使用Redisson的实现

  5. 处理锁续期问题:对于长时间任务,考虑实现锁的自动续期机制

注意事项

  1. Redis分布式锁在集群环境下可能存在脑裂问题,可以考虑使用RedLock算法

  2. 锁的获取和释放必须是原子操作,使用Lua脚本可以保证这一点

  3. 网络延迟和Redis故障需要考虑,分布式锁并不是100%可靠的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值