Skip to content

Commit

Permalink
优化分布式锁增加自动解锁功能
Browse files Browse the repository at this point in the history
  • Loading branch information
zlt2000 committed Aug 4, 2020
1 parent 0deb6ca commit 8f7f11e
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 82 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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时间后放弃
Expand All @@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
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;
Expand All @@ -36,10 +37,9 @@ public boolean saveIdempotency(T entity, DistributedLock locker, String lockKey,
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);
Expand All @@ -54,8 +54,6 @@ public boolean saveIdempotency(T entity, DistributedLock locker, String lockKey,
} else {
throw new LockException("锁等待超时");
}
} finally {
locker.unlock(lock);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
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;
Expand All @@ -14,6 +15,7 @@
/**
* redisson分布式锁实现,基本锁功能的抽象实现
* 本接口能满足绝大部分的需求,高级的锁功能,请自行扩展或直接使用原生api
* https://gitbook.cn/gitchat/activity/5f02746f34b17609e14c7d5a
*
* @author zlt
* @date 2020/5/5
Expand All @@ -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) {
Expand Down

0 comments on commit 8f7f11e

Please sign in to comment.