SpringBoot中使用注解来实现 Redis 分布式锁
发布日期:2021-04-30 21:12:18
浏览次数:87
分类:精选文章
本文共 3364 字,大约阅读时间需要 11 分钟。
Redis?????????????
??????????????????????????????????Redis????????????????????????????Redis??????????????????
????
??????????????????????????????????????????????????????????????????????????????????????????????
????????
?????????Redis????????????AOP?????????????????????????????
??????
???????????RedisLockAnnotation???????????????????????????????????
AOP???????Spring?AOP?????????????????????
??????????????????????????????????Redis?setIfAbsent???????
????????????????????????????????????????????????????
???????????????????????????????????
????
????
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface RedisLockAnnotation { int lockField() default 0; int tryCount() default 3; RedisLockTypeEnum typeEnum(); long lockTime() default 30;} ??????
@Pointcut("cn.sevenyuan.demo.aop.lock.RedisLockAnnotation")public void redisLockPC() {}@Around("cn.sevenyuan.demo.aop.lock.RedisLockAnnotation")public Object around(ProceedingJoinPoint pjp) throws Throwable { Method method = pjp.resolveMethod(); RedisLockAnnotation annotation = method.getAnnotation(RedisLockAnnotation.class); RedisLockTypeEnum typeEnum = annotation.typeEnum(); Object[] params = pjp.getArgs(); String ukString = params[annotation.lockField()].toString(); String businessKey = typeEnum.getUniqueKey(ukString); String uniqueValue = UUID.randomUUID().toString(); try { boolean isLock = redisTemplate.opsForValue().setIfAbsent(businessKey, uniqueValue); if (!isLock) { throw new Exception("?????"); } redisTemplate.expire(businessKey, annotation.lockTime(), TimeUnit.SECONDS); holderList.add(new RedisLockDefinitionHolder(businessKey, annotation.lockTime(), System.currentTimeMillis(), Thread.currentThread(), annotation.tryCount())); return pjp.proceed(); } catch (InterruptedException e) { log.error("?????"); throw new Exception("?????"); } catch (Exception e) { log.error("??????"); throw e; } finally { redisTemplate.delete(businessKey); log.info("??????Key?" + businessKey); } return null;} ??????
@Scheduled(fixedDelay = 2, initialDelay = 0)public void scheduleTask() { Iterator iterator = holderList.iterator(); while (iterator.hasNext()) { RedisLockDefinitionHolder holder = iterator.next(); if (holder == null) { iterator.remove(); continue; } // ??????? if (redisTemplate.opsForValue().get(holder.getBusinessKey()) == null) { iterator.remove(); continue; } // ???????? long currentTime = System.currentTimeMillis(); boolean shouldExtend = (holder.getLastModifyTime() + holder.getModifyPeriod()) <= currentTime; if (shouldExtend) { holder.setLastModifyTime(currentTime); redisTemplate.expire(holder.getBusinessKey(), holder.getLockTime(), TimeUnit.SECONDS); holder.setCurrentCount(holder.getCurrentCount() + 1); log.info("???????Key?" + holder.getBusinessKey() + ", try count?" + holder.getCurrentCount()); } }} ?????
???????????????????????????????????????????????????????????????????????????????????????????
?????????????????????????????????????????????????????
发表评论
最新留言
很好
[***.229.124.182]2026年06月24日 19时10分55秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
RabbitMQ - 死信、TTL原理、延迟队列安装和配置
2023-03-01
PHP数据访问的多重查询(租房子查询)
2023-03-01
RabbitMQ - 如保证消息的可靠性?(消息确认、消息持久化、失败重试机制)
2023-03-01
RabbitMQ - 基于 SpringAMQP 带你实现五种消息队列模型
2023-03-01
php数组函数分析--array_column
2023-03-01
php数组去重复数据的小例子
2023-03-01
php数组实现:哈希 +双向链表
2023-03-01
PHP数组排序函数array_multisort()函数详解(二)
2023-03-01
php数组的几个函数和超全局变量
2023-03-01
PHP文件上传详解
2023-03-01
PHP文件锁
2023-03-01
php文本框输入制定文本,php – 当用户没有向文本框输入任何内容时...
2023-03-01
PHP时间戳和日期相互转换操作总结
2023-03-01
php时间戳知识点,php 时间戳函数总结与示例
2023-03-01
php更新数据库失败,php – 无法更新MySQL数据库
2023-03-01
php机器人聊天对话框,基于AIML的PHP聊天机器人
2023-03-01
PHP查找数组中最大值与最小值
2023-03-01
php查最大值,在PHP数组中查找最大值
2023-03-01
php根据年月日计算年龄
2023-03-01