Redis实现分布式锁

注解方式实现

1、使用redission实现加锁和解锁逻辑

public interface DistributedLocker {

    RLock lock(String lockKey);

    RLock lock(String lockKey, int timeout);

    RLock lock(String lockKey, TimeUnit unit, int timeout);

    boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime);

    void unlock(String lockKey);

    void unlock(RLock lock);

}

@Service
public class RedissonDistributedLocker implements DistributedLocker {

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public RLock lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
        return lock;
    }

    @Override
    public RLock lock(String lockKey, int leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(leaseTime, TimeUnit.SECONDS);
        return lock;
    }

    @Override
    public RLock lock(String lockKey, TimeUnit unit , int timeout) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, unit);
        return lock;
    }

    @Override
    public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
            //漏洞修复
            Thread.currentThread().interrupt();
            return false;
        }
    }

    @Override
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }

    @Override
    public void unlock(RLock lock) {
        lock.unlock();
    }

}

2、创建注解

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DistributedLock {

    //锁名称
    String lockName();

    //等待时间
    int waitTime() default 5 * 1000;

    //释放时间
    int leaseTime() default 5 * 1000;

    //时间单位
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;

}

3、使用aop,对注解进行拦截

@Aspect
@Component
public class DistributedLockAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(DistributedLockAspect.class);

    @Autowired
    private DistributedLocker distributedLocker;

    @Pointcut("@annotation(com.service.aop.DistributedLock)")
    public void RlockAspect() {
        // DO Nothing
    }

    @Around("RlockAspect()")
    public Object arround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object object = null;
        RLock rLock = null;
        try {
            DistributedLock rlockInfo = getRlockInfo(proceedingJoinPoint);
            if (null != rlockInfo) {
                rLock = distributedLocker.lock(rlockInfo.lockName(), rlockInfo.timeUnit(), rlockInfo.leaseTime());
                LOGGER.info("rlockAspect rLock start " + Thread.currentThread().getName());
              
                object = proceedingJoinPoint.proceed();
            }
        } catch (Throwable e) {
            e.printStackTrace();
            LOGGER.error("rlockAspect rLock error",e);
            throw e;
        } finally {
            // 当前线程获取到锁再释放锁
            if (rLock != null && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
                LOGGER.info("rlockAspect end " + Thread.currentThread().getName());
            }
        }
        return object;
    }

    public DistributedLock getRlockInfo(ProceedingJoinPoint proceedingJoinPoint) {
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        return methodSignature.getMethod().getAnnotation(DistributedLock.class);
    }


}

4、使用

方法上加注解即可

@DistributedLock(lockName = "addDatasource")

你可能感兴趣的:(redis,分布式,数据库)