redisson 实现分布式锁
1.引入redisson依赖<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.5.4</version></dependency>2.自定义注解实现redisson分布式锁/***
·
1.引入redisson依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.5.4</version>
</dependency>
2.自定义注解实现redisson分布式锁
/**
* @Description: 基于注解的分布式式锁
* @author lz
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DistributedLock {
/**
* 锁的名称
*/
String value() default "redisson";
/**
* 锁的有效时间
*/
int leaseTime() default 10;
}
3. Redisson分布式锁注解解析器
/**
* @Description: Redisson分布式锁注解解析器
* @author lz
*/
@Aspect
@Component
@Slf4j
public class DistributedLockHandler {
@Autowired
RedissonLock redissonLock;
@Around("@annotation(distributedLock)")
public void around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) {
log.info("[开始]执行RedisLock环绕通知,获取Redis分布式锁开始");
//获取锁名称
String lockName = distributedLock.value();
//获取超时时间,默认10秒
int leaseTime = distributedLock.leaseTime();
redissonLock.lock(lockName, leaseTime);
try {
log.info("获取Redis分布式锁[成功],加锁完成,开始执行业务逻辑...");
joinPoint.proceed();
} catch (Throwable throwable) {
log.error("获取Redis分布式锁[异常],加锁失败", throwable);
throwable.printStackTrace();
} finally {
//如果该线程还持有该锁,那么释放该锁。如果该线程不持有该锁,说明该线程的锁已到过期时间,自动释放锁
if (redissonLock.isHeldByCurrentThread(lockName)) {
redissonLock.unlock(lockName);
}
}
log.info("释放Redis分布式锁[成功],解锁完成,结束业务逻辑...");
}
}
4.针对源码Redisson进行一层封装
/**
* @Description: 针对源码Redisson进行一层封装
* @author lz
*/
@Slf4j
public class RedissonLock {
private Redisson redisson;
public RedissonLock(RedissonManager redissonManager) {
this.redissonManager = redissonManager;
this.redisson = redissonManager.getRedisson();
}
public RedissonLock() {}
/**
* 加锁操作 (设置锁的有效时间)
* @param lockName 锁名称
* @param leaseTime 锁有效时间
*/
public void lock(String lockName, long leaseTime) {
RLock rLock = redisson.getLock(lockName);
rLock.lock(leaseTime,TimeUnit.SECONDS);
}
/**
* 加锁操作 (锁有效时间采用默认时间30秒)
* @param lockName 锁名称
*/
public void lock(String lockName) {
RLock rLock = redisson.getLock(lockName);
rLock.lock();
}
/**
* 加锁操作(tryLock锁,没有等待时间)
* @param lockName 锁名称
* @param leaseTime 锁有效时间
*/
public boolean tryLock(String lockName, long leaseTime) {
RLock rLock = redisson.getLock(lockName);
boolean getLock = false;
try {
getLock = rLock.tryLock( leaseTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.error("获取Redisson分布式锁[异常],lockName=" + lockName, e);
e.printStackTrace();
return false;
}
return getLock;
}
/**
* 加锁操作(tryLock锁,有等待时间)
* @param lockName 锁名称
* @param leaseTime 锁有效时间
* @param waitTime 等待时间
*/
public boolean tryLock(String lockName, long leaseTime,long waitTime) {
RLock rLock = redisson.getLock(lockName);
boolean getLock = false;
try {
getLock = rLock.tryLock( waitTime,leaseTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.error("获取Redisson分布式锁[异常],lockName=" + lockName, e);
e.printStackTrace();
return false;
}
return getLock;
}
/**
* 解锁
* @param lockName 锁名称
*/
public void unlock(String lockName) {
redisson.getLock(lockName).unlock();
}
/**
* 判断该锁是否已经被线程持有
* @param lockName 锁名称
*/
public boolean isLock(String lockName) {
RLock rLock = redisson.getLock(lockName);
return rLock.isLocked();
}
/**
* 判断该线程是否持有当前锁
* @param lockName 锁名称
*/
public boolean isHeldByCurrentThread(String lockName) {
RLock rLock = redisson.getLock(lockName);
return rLock.isHeldByCurrentThread();
}
}
5.注解使用
/**
* @author lz
* @Description: 基于注解的方式 加锁
* @date 2020/10/24 下午11:01
*/
@RestController
@Slf4j
public class AnnotatinLockController {
@Autowired
RedissonLock redissonLock;
/**
* 模拟这个是商品库存
*/
public static volatile Integer TOTAL = 10;
@GetMapping("annotatin-lock-decrease-stock")
@DistributedLock(value="goods", leaseTime=5)
public String lockDecreaseStock() throws InterruptedException {
if (TOTAL > 0) {
TOTAL--;
}
log.info("===注解模式=== 减完库存后,当前库存===" + TOTAL);
return "=================================";
}
}
更多推荐
所有评论(0)