欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > java结合redistemplate使用分布式锁案例

java结合redistemplate使用分布式锁案例

2024/10/25 5:18:59 来源:https://blog.csdn.net/weixin_41203765/article/details/141427024  浏览:    关键词:java结合redistemplate使用分布式锁案例

在Java中使用RedisTemplate结合Redis来实现分布式锁是一种常见的做法,特别适用于微服务架构或多实例部署的应用程序中,以确保数据的一致性和避免竞态条件。以下是一个简单的使用Spring Boot和RedisTemplate实现分布式锁的案例。

1. 引入依赖

首先,确保你的Spring Boot项目中已经包含了Redis相关的依赖。如果是Maven项目,可以在pom.xml中添加如下依赖:

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

2. 配置Redis

application.propertiesapplication.yml中配置Redis服务器的连接信息:

# application.properties 示例  
spring.redis.host=localhost  
spring.redis.port=6379  
spring.redis.password= # 如果Redis设置了密码,请填写

3. 实现分布式锁

使用Redis实现分布式锁的关键在于利用Redis的原子操作(如SETNXSET命令的NXPX选项)来确保锁的互斥性。在Spring Boot中,我们可以通过自定义服务或使用RedisTemplate直接操作Redis。

下面是一个简单的分布式锁实现:

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.data.redis.core.script.DefaultRedisScript;  
import org.springframework.stereotype.Service;  import java.util.Collections;  
import java.util.UUID;  
import java.util.concurrent.TimeUnit;  @Service  
public class RedisLockService {  @Autowired  private RedisTemplate<String, Object> redisTemplate;  private static final String LOCK_PREFIX = "lock:";  /**  * 尝试获取锁  * @param key 锁的key  * @param expireTime 锁的过期时间,单位秒  * @return 是否获取锁成功  */  public boolean tryLock(String key, long expireTime) {  String requestId = UUID.randomUUID().toString();  String result = redisTemplate.opsForValue().setIfAbsent(LOCK_PREFIX + key, requestId, expireTime, TimeUnit.SECONDS);  return "OK".equals(result);  }  /**  * 释放锁  * @param key 锁的key  * @param requestId 请求的唯一标识  * @return 是否释放锁成功  */  public boolean releaseLock(String key, String requestId) {  String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";  Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Collections.singletonList(LOCK_PREFIX + key), requestId);  return result != null && result > 0;  }  
}

4. 使用分布式锁

在你的业务逻辑中,可以这样使用RedisLockService

@Autowired  
private RedisLockService redisLockService;  public void criticalSection() {  String lockKey = "yourLockKey";  try {  if (redisLockService.tryLock(lockKey, 10)) { // 尝试获取锁,10秒过期  // 执行你的关键代码  // ...  }  } finally {  redisLockService.releaseLock(lockKey, requestId); // 释放锁,requestId需要是之前尝试加锁时生成的UUID  }  
}

注意:这里的requestId需要是在尝试加锁时生成的,并在释放锁时使用相同的值。实际使用中,你可能需要在调用tryLock方法之前或方法中生成requestId,并在调用releaseLock时传递它。

5. 注意事项

  • 确保锁的粒度适中,避免过细或过粗的锁导致性能问题或并发限制。
  • 考虑锁的续期问题,特别是在长时间运行的操作中。
  • 在分布式系统中,锁失败是常态,确保你的代码能够妥善处理锁失败的情况。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com