Realization of Redis distributed lock based on SpringBoot AOP aspect-oriented programming Realization of Redis distributed lock based on SpringBoot AOP aspect-oriented programming Realization of Redis distributed lock based on SpringBoot AOP aspect-oriented programming
The goal of locking is to ensure mutual exclusion of the resources it accesses. In practice, this resource is usually a string. Using redis to implement locks is mainly to put resources into redis and take advantage of its atomicity. Some subsequent operations are not allowed if this resource already exists in Redis when accessed by other threads.
Spring Boot uses Redis through RedisTemplate. In actual use, distributed locks can be used at the method level after encapsulation, which is more convenient to use, without the need to acquire and release locks everywhere.
First, define an annotation:
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited public [@interface](https://my.oschina.net/u/996807) RedisLock { //Locked resource, key for redis String value() default "default"; //lock hold time (in milliseconds) long keepMills() default 30000; //Action to take on failure LockFailAction action() default LockFailAction.CONTINUE; //Action to perform on failure -- enumeration public enum LockFailAction{ GIVEUP, CONTINUE; } //retry interval long sleepMills() default 200; //number of retries int retryTimes() default 5; }
Bean with distributed lock
[@Configuration](https://my.oschina.net/pointdance) @AutoConfigureAfter(RedisAutoConfiguration.class) public class DistributedLockAutoConfiguration { @Bean @ConditionalOnBean(RedisTemplate.class) public DistributedLock redisDistributedLock(RedisTemplate redisTemplate){ return new RedisDistributedLock(redisTemplate); } }
Aspect-Oriented Programming - Defining Aspects
@Aspect @Configuration @ConditionalOnClass(DistributedLock.class) @AutoConfigureAfter(DistributedLockAutoConfiguration.class) public class DistributedLockAspectConfiguration { private final Logger logger = LoggerFactory.getLogger(DistributedLockAspectConfiguration.class); @Autowired private DistributedLock distributedLock; @Pointcut("@annotation(com.itopener.lock.redis.spring.boot.autoconfigure.annotations.RedisLock)") private void lockPoint(){ } @Around("lockPoint()") public Object around(ProceedingJoinPoint pjp) throws Throwable{ Method method = ((MethodSignature) pjp.getSignature()).getMethod(); RedisLock redisLock = method.getAnnotation(RedisLock.class); String key = redisLock.value(); if(StringUtils.isEmpty(key)){ Object\[\] args = pjp.getArgs(); key = Arrays.toString(args); } int retryTimes = redisLock.action().equals(LockFailAction.CONTINUE) ? redisLock.retryTimes() : 0; //Acquire a distributed lock boolean lock = distributedLock.lock(key, redisLock.keepMills(), retryTimes, redisLock.sleepMills()); if(!lock) { logger.debug("get lock failed : " + key); return null; } //After executing the method, release the distributed lock logger.debug("get lock success : " + key); try { return pjp.proceed(); //execution method } catch (Exception e) { logger.error("execute locked method occured an exception", e); } finally { boolean releaseResult = distributedLock.releaseLock(key); //release distributed lock logger.debug("release lock :" + key + (releaseResult ?" success" : "failed")); } return null; } }
Instructions
- When entering this method, a distributed lock is occupied,
- When the method execution is complete, release the distributed lock
- Use the same resource, such as multiple functions of your-custom-service-redis-key, to seize the same lock. Whoever grabs it will execute first.
@RedisLock(value="your-custom-service-redis-key") public void serviceMethod(){ //Normal write method implementation }
Welcome to pay attention to my blog, there are many fine collections in it
- This article is reproduced to indicate the source (must be linked, not just text): Antetokounmpo Blog .
If you find it helpful, please like and share! Your support is my inexhaustible creative motivation! . In addition, the author has recently output the following fine content, looking forward to your attention.