注解式 redisson分布式锁
之前我加锁是在方法里面,但是有一个问题,就是没有解耦,就跟我说redis不同mysql缓存是一样的。
这里也写一个AOP,利用注解,进行方法的加锁。
首先,写一个ASPECT
@Aspect
@Component
public class RedisLockAspect {
@Autowired
private RedissonClient redissonClient;
private static final String REDIS_PREFIX = "redisson_lock:";
@Around("@annotation(redisLock)")
public Object around(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable {
String key = redisLock.key();
String lockName = redisLock.lockName();
RLock rLock = redissonClient.getLock(REDIS_PREFIX + lockName + ":" + key);
rLock.lock(redisLock.expire(),redisLock.timeUnit());
Object result = null;
try {
//执行方法
result = joinPoint.proceed();
} finally {
rLock.unlock();
}
return result;
}
}
我们在测试的时候,模拟2000个并发,之前有测试代码,你们可以直接拿来用。
@GetMapping("/test/{id}")
@RedisLock(lockName = "test", key = "test + ':' + #id")
public void aspectLock(@PathVariable String id) {
    //模拟多个资源请求输出库存情况
    //goods_num
        System.out.println("-------------线程"+id+"抢到锁------------");
        //获取成功
        int num = Integer
                .parseInt(distributedLock.getValueByKey("goods_num"));
        if(num > 0) {
            distributedLock.setValueByKey("goods_num", Integer.toString(num - 1));
            System.out.println("商品数剩余----->" + (num - 1));
        } else {
            System.out.println("商品销售完----结束了!");
    }
    System.out.println("-------------线程"+id+"结束------------");
}
标记了红色的,就是注解了。
可以看到,这个逻辑就解耦了,我们先获得锁,能获得锁的,那么就进入方法。
遮掩就可以了,代码简洁易懂。
                    
                
                
            
        
浙公网安备 33010602011771号