废话不多说,直接上代码
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.UUID;
public class JedisService {
@Autowired
private JedisPool jedisPool;
/**
*
* @param lockKey 需要锁的key
* @param second 锁的时长(单位秒)
* @param t 操作对象
* @return
* @throws Exception
*/
public String redisLock(String lockKey,int second, T t)throws Exception{
String requestId = UUID.randomUUID().toString();
//加锁时长
int expireTime = second*1000;
boolean isRun = true;
while (isRun) {
try (Jedis jedis = jedisPool.getResource()){
//尝试获得锁
boolean getLock = RedisLockTool.tryGetDistributedLock(jedis, lockKey, requestId, expireTime);
if (getLock) {
//TODO 进行其他操作(例如数据库,建议首先查是否存在数据库)
//释放锁
RedisLockTool.releaseDistributedLock(jedis, lockKey, requestId);
isRun = false;
}
} catch (Exception e) {
isRun = false;
return "程序出错,错误信息:"+e.getMessage();
} finally {
Thread.sleep(50);
}
}
return "SUCCESS";
}
}
RedisLockTool类代码:
import redis.clients.jedis.Jedis;
import java.util.Collections;
public class RedisLockTool {
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "nx";
private static final String SET_WITH_EXPIRE_TIME = "px";
private static final Long RELEASE_SUCCESS = 1L;
/**
* 尝试获取分布式锁
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
if (LOCK_SUCCESS.equals(result)) {
return true;
}
return false;
}
/**
* 释放分布式锁
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @return 是否释放成功
*/
public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
if (RELEASE_SUCCESS.equals(result)) {
return true;
}
return false;
}
}
redis相关配置:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.time.Duration;
@Configuration
@Slf4j
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private Duration timeout;
@Value("${spring.redis.jedis.pool.max-active:500}")
private int jedisMaxActive;
@Value("${spring.redis.jedis.pool.max-idle:50}")
private int jedisMaxIdle;
@Value("${spring.redis.jedis.pool.max-wait:30s}")
private Duration jedisMaxWait;
@Bean("userRedisTemplate")
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
//使用fastjson序列化
Jackson2JsonRedisSerializer<Object> j = new Jackson2JsonRedisSerializer<Object>(Object.class);
// value值的序列化采用fastJsonRedisSerializer
template.setValueSerializer(j);
template.setHashValueSerializer(j);
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
public JedisPool redisPoolFactory() throws Exception {
log.info("redis地址:" + host + ":" + port);
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 是否启用pool的jmx管理功能, 默认true
jedisPoolConfig.setJmxEnabled(true);
int redisTimeout = (int)timeout.getSeconds();
//设置最大连接数500
jedisPoolConfig.setMaxTotal(jedisMaxActive);
//设置最大空闲连接50
jedisPoolConfig.setMaxIdle(jedisMaxIdle);
//设置等待时间30s
jedisPoolConfig.setMaxWaitMillis(jedisMaxWait.getSeconds() * 1000);
/*//在获取Jedis连接时,自动检验连接是否可用
jedisPoolConfig.setTestOnBorrow(true);
//在将连接放回池中前,自动检验连接是否有效
jedisPoolConfig.setTestOnReturn(true);
//自动测试池中的空闲连接是否都是可用连接
jedisPoolConfig.setTestWhileIdle(true);*/
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, redisTimeout, password);
return jedisPool;
}
}