springboot redis分布式锁实现
时间: 2023-10-13 16:07:05 浏览: 121
在SpringBoot中使用Redis实现分布式锁是一个常见的需求。下面是一个简单的示例,展示了如何使用RedisTemplate来实现分布式锁:
首先,确保你的SpringBoot项目中已经引入了Redis的依赖。
1. 创建一个RedisLock类,用于实现分布式锁的相关逻辑:
```java
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class RedisLock {
private RedisTemplate<String, String> redisTemplate;
public RedisLock(RedisConnectionFactory redisConnectionFactory) {
this.redisTemplate = new RedisTemplate<>();
this.redisTemplate.setConnectionFactory(redisConnectionFactory);
this.redisTemplate.afterPropertiesSet();
}
public boolean lock(String key, String value, long expireTime) {
ValueOperations<String, String> operations = redisTemplate.opsForValue();
// SETNX命令可以设置键值对,只有在键不存在时才会设置成功
boolean success = operations.setIfAbsent(key, value);
if (success) {
// 设置成功后,为了防止死锁,给锁设置过期时间
redisTemplate.expire(key, expireTime, TimeUnit.MILLISECONDS);
return true;
}
return false;
}
public void unlock(String key, String value) {
ValueOperations<String, String> operations = redisTemplate.opsForValue();
// 释放锁时,先判断锁的值是否匹配,避免误解锁
if (value.equals(operations.get(key))) {
redisTemplate.delete(key);
}
}
}
```
2. 在需要加锁的地方,注入RedisLock实例,调用lock方法获取锁:
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
private RedisLock redisLock;
@Autowired
public MyController(RedisLock redisLock) {
this.redisLock = redisLock;
}
@GetMapping("/doSomething")
public String doSomething() {
String lockKey = "lockKey";
String lockValue = "lockValue";
long expireTime = 5000; // 锁的过期时间
if (redisLock.lock(lockKey, lockValue, expireTime)) {
try {
// 加锁成功后,处理业务逻辑
// ...
return "Success";
} finally {
// 无论业务逻辑是否成功,都要释放锁
redisLock.unlock(lockKey, lockValue);
}
} else {
// 获取锁失败,可能有其他线程正在处理业务逻辑
return "Failed";
}
}
}
```
在上述示例中,我们使用了Redis的SETNX命令来设置锁,只有在键不存在时才会设置成功。同时为了防止死锁,我们给锁设置了一个过期时间。在释放锁时,先判断锁的值是否匹配,避免误解锁。
通过使用这种方式,我们可以实现简单的分布式锁功能。当多个线程或多个应用程序同时请求锁时,只有一个线程或应用程序能够获取到锁,从而保证并发安全。
阅读全文