springboot 对 redis 分布式锁的支持
步骤:
- 引入依赖
<!-- springboot整合redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 加锁以及 解锁工具类
package com.hzrys.atplatform.finance.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Component
@Slf4j
public class RedisLock {
@Autowired
private StringRedisTemplate stringRedisTemplate;
public boolean lock(String key, String value) {
if (stringRedisTemplate.opsForValue().setIfAbsent(key, value)) {
return true;
}
String currentValue = stringRedisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) {
String oldValue = stringRedisTemplate.opsForValue().getAndSet(key, value);
if (!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)) {
return true;
}
}
return false;
}
public void unlock(String key, String value) {
try {
String currentValue = stringRedisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
stringRedisTemplate.opsForValue().getOperations().delete(key);
}
} catch (Exception e) {
log.error("[Redis分布式锁] 解锁出现异常了,{}", e);
}
}
}
- 业务代码的加解锁过程
private static final int TIMEOUT = 10 * 1000;
@org.junit.Test
public void testRedisLock2() throws InterruptedException {
boolean flag = true;
int count = 0;
while (flag) {
count++;
System.out.println("线程三:查询第"+count+"次!");
long time = System.currentTimeMillis() + TIMEOUT;
flag = redisLock.lock("finance:***Service-methodName", String.valueOf(time));
if (flag) {
System.out.println("我被锁了 谁也别想再访问我!");
Thread.sleep(1000*8);
redisLock.unlock("finance:***Service-methodName", String.valueOf(time));
flag = false;
System.out.println("操作完成 锁已被我释放!");
} else {
flag = true;
}
}
}