提交 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 { ...@@ -21,10 +21,17 @@ public interface DistributedLock {
* @param isFair 是否公平锁 * @param isFair 是否公平锁
* @return 锁对象 * @return 锁对象
*/ */
Object lock(String key, long leaseTime, TimeUnit unit, boolean isFair) throws Exception; ZLock 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; default ZLock lock(String key, long leaseTime, TimeUnit unit) throws Exception {
Object lock(String key) 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时间后放弃 * 尝试获取锁,如果锁不可用则等待最多waitTime时间后放弃
...@@ -35,14 +42,29 @@ public interface DistributedLock { ...@@ -35,14 +42,29 @@ public interface DistributedLock {
* @param unit {@code waitTime} 和 {@code leaseTime} 参数的时间单位 * @param unit {@code waitTime} 和 {@code leaseTime} 参数的时间单位
* @return 锁对象,如果获取锁失败则为null * @return 锁对象,如果获取锁失败则为null
*/ */
Object tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws Exception; ZLock 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; default ZLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit) throws Exception {
Object tryLock(String key, long waitTime, 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 锁对象 * @param lock 锁对象
*/ */
void unlock(Object lock) throws Exception; 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; ...@@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.central.common.exception.IdempotencyException; import com.central.common.exception.IdempotencyException;
import com.central.common.exception.LockException; import com.central.common.exception.LockException;
import com.central.common.lock.DistributedLock; import com.central.common.lock.DistributedLock;
import com.central.common.lock.ZLock;
import com.central.common.service.ISuperService; import com.central.common.service.ISuperService;
import java.io.Serializable; import java.io.Serializable;
...@@ -36,10 +37,9 @@ public class SuperServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, ...@@ -36,10 +37,9 @@ public class SuperServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M,
if (StrUtil.isEmpty(lockKey)) { if (StrUtil.isEmpty(lockKey)) {
throw new LockException("lockKey is null"); throw new LockException("lockKey is null");
} }
Object lock = null; try (
try { ZLock lock = locker.tryLock(lockKey, 10, 60, TimeUnit.SECONDS);
//加锁 ) {
lock = locker.tryLock(lockKey, 10, 60, TimeUnit.SECONDS);
if (lock != null) { if (lock != null) {
//判断记录是否已存在 //判断记录是否已存在
int count = super.count(countWrapper); int count = super.count(countWrapper);
...@@ -54,8 +54,6 @@ public class SuperServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, ...@@ -54,8 +54,6 @@ public class SuperServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M,
} else { } else {
throw new LockException("锁等待超时"); throw new LockException("锁等待超时");
} }
} finally {
locker.unlock(lock);
} }
} }
......
...@@ -3,6 +3,7 @@ package com.central.common.redis.lock; ...@@ -3,6 +3,7 @@ package com.central.common.redis.lock;
import com.central.common.constant.CommonConstant; import com.central.common.constant.CommonConstant;
import com.central.common.exception.LockException; import com.central.common.exception.LockException;
import com.central.common.lock.DistributedLock; import com.central.common.lock.DistributedLock;
import com.central.common.lock.ZLock;
import org.redisson.api.RLock; import org.redisson.api.RLock;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -14,6 +15,7 @@ import java.util.concurrent.TimeUnit; ...@@ -14,6 +15,7 @@ import java.util.concurrent.TimeUnit;
/** /**
* redisson分布式锁实现,基本锁功能的抽象实现 * redisson分布式锁实现,基本锁功能的抽象实现
* 本接口能满足绝大部分的需求,高级的锁功能,请自行扩展或直接使用原生api * 本接口能满足绝大部分的需求,高级的锁功能,请自行扩展或直接使用原生api
* https://gitbook.cn/gitchat/activity/5f02746f34b17609e14c7d5a
* *
* @author zlt * @author zlt
* @date 2020/5/5 * @date 2020/5/5
...@@ -27,52 +29,33 @@ public class RedissonDistributedLock implements DistributedLock { ...@@ -27,52 +29,33 @@ public class RedissonDistributedLock implements DistributedLock {
@Autowired @Autowired
private RedissonClient redisson; private RedissonClient redisson;
private RLock getLock(String key, boolean isFair) { private ZLock getLock(String key, boolean isFair) {
RLock lock;
if (isFair) { 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 @Override
public RLock lock(String key, long leaseTime, TimeUnit unit, boolean isFair) { public ZLock lock(String key, long leaseTime, TimeUnit unit, boolean isFair) {
RLock lock = getLock(key, isFair); ZLock zLock = getLock(key, isFair);
RLock lock = (RLock)zLock.getLock();
lock.lock(leaseTime, unit); lock.lock(leaseTime, unit);
return lock; return zLock;
}
@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);
} }
@Override @Override
public RLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws InterruptedException { public ZLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws InterruptedException {
RLock lock = getLock(key, isFair); ZLock zLock = getLock(key, isFair);
RLock lock = (RLock)zLock.getLock();
if (lock.tryLock(waitTime, leaseTime, unit)) { if (lock.tryLock(waitTime, leaseTime, unit)) {
return lock; return zLock;
} }
return null; 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 @Override
public void unlock(Object lock) { public void unlock(Object lock) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册