Browse Source

♻️ 移除冗余代码 && 增加快速失败

3.x
Yangkai.Shen 2 years ago
parent
commit
721dabf2b4
7 changed files with 42 additions and 98 deletions
  1. +5
    -0
      demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/annotation/DLock.java
  2. +31
    -11
      demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/aop/DistributedLockAspect.java
  3. +3
    -3
      demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/api/DistributedLock.java
  4. +0
    -27
      demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/api/DistributedLockService.java
  5. +0
    -47
      demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/api/impl/DistributedLockServiceImpl.java
  6. +2
    -9
      demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/autoconfigure/DistributedLockAutoConfiguration.java
  7. +1
    -1
      demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/service/StockService.java

+ 5
- 0
demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/annotation/DLock.java View File

@@ -31,4 +31,9 @@ public @interface DLock {
* @return 锁的时间单位
*/
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;

/**
* @return 快速失败,true: 限流,拿不到锁,直接失败;false: 不限流,接收所有请求,阻塞执行
*/
boolean fastFail() default false;
}

+ 31
- 11
demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/aop/DistributedLockAspect.java View File

@@ -1,7 +1,8 @@
package com.xkcoding.distributed.lock.aop;

import com.xkcoding.distributed.lock.annotation.DLock;
import com.xkcoding.distributed.lock.api.DistributedLockService;
import com.xkcoding.distributed.lock.api.DistributedLock;
import com.xkcoding.distributed.lock.api.DistributedLockClient;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
@@ -27,24 +28,43 @@ import java.util.concurrent.TimeUnit;
@Aspect
@RequiredArgsConstructor
public class DistributedLockAspect {
private final DistributedLockService distributedLockService;
private final DistributedLockClient distributedLockClient;

@Around("@annotation(lock)")
public Object around(ProceedingJoinPoint pjp, DLock lock) throws Throwable {
@Around("@annotation(dLock)")
public Object around(ProceedingJoinPoint pjp, DLock dLock) throws Throwable {
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
Object[] args = pjp.getArgs();
String lockKey = lock.lockKey();
String lockKey = dLock.lockKey();
lockKey = parseExpression(lockKey, method, args);

long timeout = lock.lockTime();
TimeUnit timeUnit = lock.timeUnit();
return distributedLockService.lock(lockKey, timeout, timeUnit, () -> {
long timeout = dLock.lockTime();
TimeUnit timeUnit = dLock.timeUnit();

DistributedLock lock = distributedLockClient.getLock(lockKey, timeout, timeUnit);

if (dLock.fastFail()) {
if (lock.tryLock()) {
try {
return pjp.proceed();
} catch (Throwable t) {
throw new RuntimeException(t);
} finally {
lock.unlock();
}
} else {
throw new RuntimeException("请勿重复提交!");
}
} else {
lock.lock();
try {
return pjp.proceed();
} catch (Throwable e) {
throw new RuntimeException(e);
} catch (Throwable t) {
throw new RuntimeException(t);
} finally {
lock.unlock();
}
});
}

}

/**


+ 3
- 3
demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/api/DistributedLock.java View File

@@ -16,15 +16,15 @@ public abstract class DistributedLock implements Lock {
/**
* 锁的标识
*/
private final String lockKey;
protected final String lockKey;
/**
* 锁的时间
*/
private final long lockTime;
protected final long lockTime;
/**
* 锁的时间单位
*/
private final TimeUnit timeUnit;
protected final TimeUnit timeUnit;

protected DistributedLock(String lockKey, long lockTime, TimeUnit timeUnit) {
this.lockKey = lockKey;


+ 0
- 27
demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/api/DistributedLockService.java View File

@@ -1,27 +0,0 @@
package com.xkcoding.distributed.lock.api;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
* <p>
* 分布式锁实现
* </p>
*
* @author yangkai.shen
* @date 2022-09-02 21:11
*/
public interface DistributedLockService {

/**
* 锁
*
* @param lockKey 锁的标识
* @param lockTime 锁的时间
* @param timeUnit 锁的时间单位
* @param execute 执行逻辑
* @param <T> 返回值类型
* @return 返回值
*/
<T> T lock(String lockKey, long lockTime, TimeUnit timeUnit, Supplier<T> execute);
}

+ 0
- 47
demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/api/impl/DistributedLockServiceImpl.java View File

@@ -1,47 +0,0 @@
package com.xkcoding.distributed.lock.api.impl;

import com.xkcoding.distributed.lock.api.DistributedLock;
import com.xkcoding.distributed.lock.api.DistributedLockClient;
import com.xkcoding.distributed.lock.api.DistributedLockService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
* <p>
* 分布式锁实现
* </p>
*
* @author yangkai.shen
* @date 2022-09-02 21:41
*/
@Slf4j
@RequiredArgsConstructor
public class DistributedLockServiceImpl implements DistributedLockService {
private final DistributedLockClient distributedLockClient;

/**
* 锁
*
* @param lockKey 锁
* @param timeout 超时时间
* @param timeUnit 超时单位
* @param execute 执行逻辑
* @return 返回值
*/
@Override
public <T> T lock(String lockKey, long timeout, TimeUnit timeUnit, Supplier<T> execute) {
DistributedLock lock = distributedLockClient.getLock(lockKey, timeout, timeUnit);
lock.lock();

try {
return execute.get();
} catch (Throwable t) {
throw new RuntimeException(t);
} finally {
lock.unlock();
}
}
}

+ 2
- 9
demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/autoconfigure/DistributedLockAutoConfiguration.java View File

@@ -2,8 +2,6 @@ package com.xkcoding.distributed.lock.autoconfigure;

import com.xkcoding.distributed.lock.aop.DistributedLockAspect;
import com.xkcoding.distributed.lock.api.DistributedLockClient;
import com.xkcoding.distributed.lock.api.DistributedLockService;
import com.xkcoding.distributed.lock.api.impl.DistributedLockServiceImpl;
import com.xkcoding.distributed.lock.api.impl.DummyDistributedLockClient;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -28,12 +26,7 @@ public class DistributedLockAutoConfiguration {
}

@Bean
public DistributedLockService distributedLockService(DistributedLockClient distributedLockClient) {
return new DistributedLockServiceImpl(distributedLockClient);
}

@Bean
public DistributedLockAspect distributedLockAspect(DistributedLockService distributedLockService) {
return new DistributedLockAspect(distributedLockService);
public DistributedLockAspect distributedLockAspect(DistributedLockClient distributedLockClient) {
return new DistributedLockAspect(distributedLockClient);
}
}

+ 1
- 1
demo-distributed-lock/demo-distributed-lock-api/src/main/java/com/xkcoding/distributed/lock/service/StockService.java View File

@@ -26,7 +26,7 @@ public class StockService {
/**
* 减货物
*/
@DLock(lockKey = "'lock_stock_'+#stockId", lockTime = 3000, timeUnit = TimeUnit.MICROSECONDS)
@DLock(lockKey = "'lock_stock_'+#stockId", lockTime = 3000, timeUnit = TimeUnit.MICROSECONDS, fastFail = false)
public void reduceStock(Long stockId) {
// 先查询库存是否充足
Stock stock = this.stockMapper.selectById(stockId);


Loading…
Cancel
Save