redis分布式锁的stringRedisTemplate实现

4 篇文章 0 订阅

在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等。那具体什么是分布式锁,分布式锁应用在哪些业务场景、如何来实现分布式锁呢?本文采用stringRedisTemplate来实现分布式锁.

1:什么是分布式锁?

在单机应用下的并发编程中,我们通过锁(synchronized 、Lock),来避免由于竞争而造成的数据不一致问题。而分布式锁,就是为了解决分布式应用中的数据不一致问题.通常使用redis分布式锁.

2:分布式锁的条件

  • 在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行
  • 高可用的获取锁与释放锁
  • 高性能的获取锁与释放锁
  • 具备可重入特性(可理解为重新进入,由多于一个任务并发使用,而不必担心数据错误)
  • 具备锁失效机制,防止死锁
  • 具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败

3:stringRedisTemplate实现分布式锁

加锁

加锁的话,需要有2个参数,( key保证唯一性, value为锁的存活时间)

 public boolean lock(String key, String value) {
          //判断key是否为空, StringUtil是自己写的工具类  
        if (StringUtil.isNullOrEmpty(key)) return false;

        //默认锁的存活时间为5分钟
        if (StringUtil.isNullOrEmpty(value)) value = System.currentTimeMillis() + 60000 * 5 + "";

        //采用stringRedisTemplate.opsForValue().setIfAbsent的方法加锁
        if (stringRedisTemplate.opsForValue().setIfAbsent(key, value)) {
            return true;
        }

        //如果get找不到对应的key值,或者系统当前时间大于锁存活时间,判断锁失效
        String current_value = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtil.isNullOrEmpty(current_value)
                //超时了
                && Long.parseLong(current_value) < System.currentTimeMillis()) {
            String old_value = stringRedisTemplate.opsForValue().getAndSet(key, value);
            if (!StringUtil.isNullOrEmpty(current_value)
                    && old_value.equals(current_value)) {
                return true;
            }
        }
        return false;
    }

解锁

解锁就很简单了,如果判断key存在,就删除掉key就完成了解锁.

public void unlock(String key, String value) {
        try {
            if (stringRedisTemplate.opsForValue().get(key).equals(value)) {
                stringRedisTemplate.opsForValue().getOperations().delete(key);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

因博主水平有限,代码中的不足之处请多多指正.

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在Spring Boot中使用Redis分布式锁可以通过以下步骤实现: 1. 添加Redis依赖:在`pom.xml`文件中添加Redis相关的依赖,例如`spring-boot-starter-data-redis`。 2. 配置Redis连接信息:在`application.properties`(或者`application.yml`)文件中配置Redis的连接信息,包括主机名、端口号、密码等。 3. 创建Redis分布式锁的工具类:可以创建一个名为`RedisLockUtil`的工具类,其中包含获取锁、释放锁等方法的实现。 ```java @Component public class RedisLockUtil { private static final long DEFAULT_LOCK_EXPIRE = 30000; // 默认锁的过期时间,30秒 @Autowired private StringRedisTemplate redisTemplate; /** * 获取锁 * @param lockKey 锁的键 * @param requestId 请求标识,用于区分不同的客户端 * @param expireTime 锁的过期时间 * @return true表示获取锁成功,false表示获取锁失败 */ public boolean tryLock(String lockKey, String requestId, long expireTime) { Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.MILLISECONDS); return result != null && result; } /** * 释放锁 * @param lockKey 锁的键 * @param requestId 请求标识,用于判断是否有权释放锁 */ public void releaseLock(String lockKey, String requestId) { String value = redisTemplate.opsForValue().get(lockKey); if (value != null && value.equals(requestId)) { redisTemplate.delete(lockKey); } } } ``` 4. 在需要加锁的地方使用Redis分布式锁: ```java @Autowired private RedisLockUtil redisLockUtil; public void doSomethingWithLock() { String lockKey = "lock:key"; String requestId = UUID.randomUUID().toString(); long expireTime = 5000; // 锁的过期时间为5秒 boolean locked = redisLockUtil.tryLock(lockKey, requestId, expireTime); if (locked) { try { // 获取到锁,执行业务逻辑 // ... } finally { // 释放锁 redisLockUtil.releaseLock(lockKey, requestId); } } else { // 获取锁失败,可能有其他线程正在处理 // ... } } ``` 以上是一个简单的使用Redis分布式锁的示例,你可以根据自己的实际需求进行调整和扩展。同时,还可以结合AOP、注解等方式来简化和统一锁的使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值