提交 8f7f11e1 编写于 作者: zlt2000's avatar zlt2000

优化分布式锁增加自动解锁功能

上级 0deb6ca2
package com.central.common.config;
import com.central.common.feign.UserService;
import com.central.common.resolver.ClientArgumentResolver;
import com.central.common.resolver.TokenArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/**
* 公共配置类, 一些公共工具配置
*
* @author zlt
* @date 2018/8/25
*/
public class LoginArgResolverConfig implements WebMvcConfigurer {
@Lazy
@Autowired
private UserService userService;
/**
* Token参数解析
*
* @param argumentResolvers 解析类
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
//注入用户信息
argumentResolvers.add(new TokenArgumentResolver(userService));
//注入应用信息
argumentResolvers.add(new ClientArgumentResolver());
}
}
......@@ -21,10 +21,17 @@ public interface DistributedLock {
* @param isFair 是否公平锁
* @return 锁对象
*/
Object lock(String key, long leaseTime, TimeUnit unit, boolean isFair) throws Exception;
Object lock(String key, long leaseTime, TimeUnit unit) throws Exception;
Object lock(String key, boolean isFair) throws Exception;
Object lock(String key) throws Exception;
ZLock lock(String key, long leaseTime, TimeUnit unit, boolean isFair) throws Exception;
default ZLock lock(String key, long leaseTime, TimeUnit unit) throws Exception {
return this.lock(key, leaseTime, unit, false);
}
default ZLock lock(String key, boolean isFair) throws Exception {
return this.lock(key, -1, null, isFair);
}
default ZLock lock(String key) throws Exception {
return this.lock(key, -1, null, false);
}
/**
* 尝试获取锁,如果锁不可用则等待最多waitTime时间后放弃
......@@ -35,14 +42,29 @@ public interface DistributedLock {
* @param unit {@code waitTime} 和 {@code leaseTime} 参数的时间单位
* @return 锁对象,如果获取锁失败则为null
*/
Object tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws Exception;
Object tryLock(String key, long waitTime, long leaseTime, TimeUnit unit) throws Exception;
Object tryLock(String key, long waitTime, TimeUnit unit, boolean isFair) throws Exception;
Object tryLock(String key, long waitTime, TimeUnit unit) throws Exception;
ZLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws Exception;
default ZLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit) throws Exception {
return this.tryLock(key, waitTime, leaseTime, unit, false);
}
default ZLock tryLock(String key, long waitTime, TimeUnit unit, boolean isFair) throws Exception {
return this.tryLock(key, waitTime, -1, unit, isFair);
}
default ZLock tryLock(String key, long waitTime, TimeUnit unit) throws Exception {
return this.tryLock(key, waitTime, -1, unit, false);
}
/**
* 释放锁
* @param lock 锁对象
*/
void unlock(Object lock) throws Exception;
/**
* 释放锁
* @param zLock 锁抽象对象
*/
default void unlock(ZLock zLock) throws Exception {
this.unlock(zLock.getLock());
}
}
package com.central.common.lock;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 锁对象抽象
*
* @author zlt
* @date 2020/7/28
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@AllArgsConstructor
public class ZLock implements AutoCloseable {
@Getter
private final Object lock;
private final DistributedLock locker;
@Override
public void close() throws Exception {
locker.unlock(lock);
}
}
......@@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.central.common.exception.IdempotencyException;
import com.central.common.exception.LockException;
import com.central.common.lock.DistributedLock;
import com.central.common.lock.ZLock;
import com.central.common.service.ISuperService;
import java.io.Serializable;
......@@ -36,10 +37,9 @@ public class SuperServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M,
if (StrUtil.isEmpty(lockKey)) {
throw new LockException("lockKey is null");
}
Object lock = null;
try {
//加锁
lock = locker.tryLock(lockKey, 10, 60, TimeUnit.SECONDS);
try (
ZLock lock = locker.tryLock(lockKey, 10, 60, TimeUnit.SECONDS);
) {
if (lock != null) {
//判断记录是否已存在
int count = super.count(countWrapper);
......@@ -54,8 +54,6 @@ public class SuperServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M,
} else {
throw new LockException("锁等待超时");
}
} finally {
locker.unlock(lock);
}
}
......
......@@ -3,6 +3,7 @@ package com.central.common.redis.lock;
import com.central.common.constant.CommonConstant;
import com.central.common.exception.LockException;
import com.central.common.lock.DistributedLock;
import com.central.common.lock.ZLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -14,6 +15,7 @@ import java.util.concurrent.TimeUnit;
/**
* redisson分布式锁实现,基本锁功能的抽象实现
* 本接口能满足绝大部分的需求,高级的锁功能,请自行扩展或直接使用原生api
* https://gitbook.cn/gitchat/activity/5f02746f34b17609e14c7d5a
*
* @author zlt
* @date 2020/5/5
......@@ -27,52 +29,33 @@ public class RedissonDistributedLock implements DistributedLock {
@Autowired
private RedissonClient redisson;
private RLock getLock(String key, boolean isFair) {
private ZLock getLock(String key, boolean isFair) {
RLock lock;
if (isFair) {
return redisson.getFairLock(CommonConstant.LOCK_KEY_PREFIX + key);
lock = redisson.getFairLock(CommonConstant.LOCK_KEY_PREFIX + key);
} else {
lock = redisson.getLock(CommonConstant.LOCK_KEY_PREFIX + key);
}
return redisson.getLock(CommonConstant.LOCK_KEY_PREFIX + key);
return new ZLock(lock, this);
}
@Override
public RLock lock(String key, long leaseTime, TimeUnit unit, boolean isFair) {
RLock lock = getLock(key, isFair);
public ZLock lock(String key, long leaseTime, TimeUnit unit, boolean isFair) {
ZLock zLock = getLock(key, isFair);
RLock lock = (RLock)zLock.getLock();
lock.lock(leaseTime, unit);
return lock;
}
@Override
public RLock lock(String key, long leaseTime, TimeUnit unit) {
return lock(key, leaseTime, unit, false);
}
@Override
public RLock lock(String key, boolean isFair) {
return lock(key, -1, null, isFair);
}
@Override
public RLock lock(String key) {
return lock(key, -1, null, false);
return zLock;
}
@Override
public RLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws InterruptedException {
RLock lock = getLock(key, isFair);
public ZLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws InterruptedException {
ZLock zLock = getLock(key, isFair);
RLock lock = (RLock)zLock.getLock();
if (lock.tryLock(waitTime, leaseTime, unit)) {
return lock;
return zLock;
}
return null;
}
@Override
public RLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
return tryLock(key, waitTime, leaseTime, unit, false);
}
@Override
public RLock tryLock(String key, long waitTime, TimeUnit unit, boolean isFair) throws InterruptedException {
return tryLock(key, waitTime, -1, unit, isFair);
}
@Override
public RLock tryLock(String key, long waitTime, TimeUnit unit) throws InterruptedException {
return tryLock(key, waitTime, -1, unit, false);
}
@Override
public void unlock(Object lock) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册