背景
最近项目里使用到分布式锁, 发现项目中的加锁操作有过多的重复代码, 故尝试将其提取出来。
新增工具类: RedissonHelpUtil
/**
* 分布式锁帮助类
*
* @author wuruixu
* @date 2021/9/14 15:38
*/
@Slf4j
public class RedissonHelpUtil {
/**
* 等待时间 / 秒
*/
public static final Integer WAIT_TIME = 0;
/**
* 过期时间 / 秒
*/
public static final Integer LEASE_TIME = 30;
@Autowired
RedissonClient redissonClient;
private static RedissonHelpUtil redissonHelpUtil;
@PostConstruct
public void init() {
redissonHelpUtil = this;
}
/**
* 对方法加分布式锁 (默认的等待时间及过期时间)
*
* @param redisKey 分布式锁的key
* @return
* @author wrx
* @date 2021/9/14 16:00
*/
public static <T> T tryLock(String redisKey, Supplier<T> supplier) {
return tryLock(redisKey, WAIT_TIME, LEASE_TIME, supplier);
}
/**
* 对方法加分布式锁 (自定义等待时间及过期时间)
*
* @param redisKey 分布式锁主键
* @param waitTime 等待时间
* @param leaseTime 过期时间
* @param supplier 自定义实现方法
* @return
* @author wrx
* @date 2021/9/14 16:34
*/
public static <T> T tryLock(String redisKey, Integer waitTime, Integer leaseTime, Supplier<T> supplier) {
RLock lock = redissonHelpUtil.redissonClient.getLock(redisKey);
try {
if (lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS)) {
log.info("获取锁成功:{}", redisKey);
return supplier.get();
} else {
log.info("获取锁失败:{}", redisKey);
throw new ServiceException(CodeMsg.LOCK_ERROR);
}
} catch (ServiceException e) {
log.info(ExceptionUtil.stacktraceToString(e));
throw new ServiceException(e.getCodeMsg(), e);
} catch (InterruptedException e) {
log.info(ExceptionUtil.stacktraceToString(e));
throw new ServiceException(e);
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
该demo使用@Bean的形式加入spring容器, 看自己需要调整
使用示例
@Override
public Boolean platformPenaltyProcessLock(String tdecId) {
String redisKey = RedisConstants.PENALTY_PROCESS + tdecId;
return RedissonHelpUtil.tryLock(redisKey, () -> platformPenaltyProcess(tdecId));
}
使用该工具, 加锁只需要传入redisKey即可