封装redis分布式锁
import com.yonghui.core.exception.RRException;
import com.yonghui.yh.rme.srm.common.enums.BizError;
import com.yonghui.yh.rme.srm.common.util.CheckUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.RedissonMultiLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@Component
@Slf4j
public class RedisDistributeLock {
@Autowired
private RedissonClient redissonClient;
@Autowired
private TransactionTemplate transactionTemplate;
private static final String CACHE_LOCK= "yh:suppliercenter:view:";
public <T, R> R lock(String lockKey, T t, Function<T, R> function) {
CheckUtils.isBlank(lockKey, BizError.REDIS_KEY_NOT_NULL);
RLock lock = redissonClient.getLock(lockKey);
try {
log.error("DistributeLock process Lock already exists! lockKey = {}", lockKey);
CheckUtils.isTrue(!lock.tryLock(), BizError.REDIS_CACHE_LOCKED);
return function.apply(t);
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
public <T, R> R lockNoWait(String lockKey, T t, Function<T, R> function) {
CheckUtils.isBlank(lockKey, BizError.REDIS_KEY_NOT_NULL);
RLock lock = redissonClient.getLock(lockKey);
try {
log.error("DistributeLock process Lock already exists! lockKey = {}", lockKey);
CheckUtils.isTrue(!lock.tryLock(-1, TimeUnit.MILLISECONDS), BizError.REDIS_CACHE_LOCKED);
return function.apply(t);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RRException(BizError.REDIS_ERROR_LOCKED);
}finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
public <T, R> R multiLock(List<String> lockKeys, T t, Function<T, R> function) {
CheckUtils.isEmpty(lockKeys, BizError.REDIS_KEY_NOT_NULL);
List<RLock> locks = lockKeys.stream().map(o -> {
RLock rLock = redissonClient.getLock(o);
return rLock;
}).collect(Collectors.toList());
RLock[] rLocks = locks.toArray(new RLock[locks.size()]);
RedissonMultiLock lock = new RedissonMultiLock(rLocks);
try {
log.error("DistributeLock process Lock already exists! lockKey = {}", lockKeys);
CheckUtils.isTrue(!lock.tryLock(), BizError.REDIS_CACHE_LOCKED);
return function.apply(t);
} finally {
lock.unlock();
}
}
public <R> R lockSupplier(String lockKey, Supplier<R> supplier) {
CheckUtils.isBlank(lockKey, BizError.REDIS_KEY_NOT_NULL);
RLock lock = redissonClient.getLock(CACHE_LOCK + lockKey);
try {
log.error("DistributeLock process Lock already exists! lockKey = {}", lockKey);
CheckUtils.isTrue(!lock.tryLock(), BizError.REDIS_CACHE_LOCKED);
return supplier.get();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
public <T, R> R lockTransaction(String lockKey, T t, Function<T, R> function) {
CheckUtils.isBlank(lockKey, BizError.REDIS_KEY_NOT_NULL);
RLock lock = redissonClient.getLock(CACHE_LOCK +lockKey);
try {
log.error("DistributeLock process Lock already exists! lockKey = {}", lockKey);
CheckUtils.isTrue(!lock.tryLock(), BizError.REDIS_CACHE_LOCKED);
return transactionTemplate.execute(status -> {
return function.apply(t);
});
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}