如何用AOP注解方式实现redis分布式抢占锁
发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,本篇内容主要讲解"如何用AOP注解方式实现redis分布式抢占锁",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何用AOP注解方式实现redis分布式抢占
千家信息网最后更新 2025年12月01日如何用AOP注解方式实现redis分布式抢占锁
本篇内容主要讲解"如何用AOP注解方式实现redis分布式抢占锁",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何用AOP注解方式实现redis分布式抢占锁"吧!
摘要
很多项目中都会有一些需要做定时跑批的任务需求,大多数是通过spring注解的方式实现的,但是到了生产环境,多节点的部署可能会造成定时任务的多节点同时触发而可能会出现脏数据。之前的处理方案是通过在字典里配置指定生产节点处理定时任务。虽然此方法也能实现需求,但总觉得很low,所以自己就通过JAVA的AOP方式利用redis实现了一套分布式抢占锁,通过注解的方式解决生产环境多节点部署带来的定时任务触发。
废话不多说,直接上代码--> 1、先自定义一个注解
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * @author v_liuwen * @date 2018/12/27 */@Target({ElementType.METHOD,ElementType.TYPE}) // 作用到类,方法,接口上等@Retention(RetentionPolicy.RUNTIME) // 在运行时可以获取public @interface RedisLock {}2、再新建一个切面类
import org.apache.commons.lang3.StringUtils;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import top.qrainly.bj_demo.job.springtask.scheduleJob.utils.RedisLockUtils;/** * @author v_liuwen * @date 2018/12/27 */@Aspect@Componentpublic class RedisLockAspect { private static Logger logger = LoggerFactory.getLogger(RedisLockAspect.class); /** * 切面 加有 RedisLock 的 service 方法 */ @Pointcut("@annotation(redisLock)") private void cutMethod(RedisLock redisLock) { } @Before("cutMethod(redisLock)") public void doAccessCheck(JoinPoint point,RedisLock redisLock) throws NoSuchMethodException { logger.info("********************************【Before】开始进入AOP切入**************************************"); } @After("cutMethod(redisLock)") public void after(JoinPoint point,RedisLock redisLock) { logger.info("********************************【after】AOP切入完成**************************************"); } @AfterThrowing("cutMethod(redisLock)") public void doAfterThrow(RedisLock redisLock) { logger.info("AfterThrowing..."); } @Around("cutMethod(redisLock)") public void around(ProceedingJoinPoint point,RedisLock redisLock){ String name = point.getSignature().getName(); Class> classTarget = point.getTarget().getClass(); System.out.println("--------------------------------------->>>AOP切入 方法名:"+name+"<<<-----------------------------------------------------"); System.out.println("--------------------------------------->>>AOP切入 类名:"+classTarget.getSimpleName()+"<<<-----------------------------------------------------"); //获取redis锁 Boolean lock = RedisLockUtils.acquireRedisLock(StringUtils.join(classTarget.getSimpleName(),name), 5); if(lock){ try { point.proceed(); } catch (Throwable throwable) { logger.error("AOP 代理执行失败"); } } }}3、在需求做定时任务的方法上添加自定义注解@RedisLock
/** * 测试批处理 */ @Override @RedisLock public void syncTest() { try{ //获取所有需要同步状态的付款单据 List allNeedSyncStatusForPayment = batchDAO.getAllNeedSyncStatusForPayment(); SimpleDateFormat sdf = new SimpleDateFormat(); System.out.println("*****************************************"+sdf.format(new Date())+"开始***********************************************"); System.out.println(JSON.toJSONString(allNeedSyncStatusForPayment)); System.out.println("*****************************************"+sdf.format(new Date())+"结束***********************************************"); }catch (Exception e){ logger.error(e.getMessage()); } } 4、注意事项: 4.1 注解不要放在service层 反射代理会绕过spring注解
补充RedisLockUtils
/** * @author v_liuwen * @date 2018/12/26 */public class RedisLockUtils { /** * 日志打印 */ private static Logger logger = LoggerFactory.getLogger(RedisLockUtils.class); private static Jedis jedis; /** * 获取jedis * * @return */ public static Jedis getJedis() { Jedis jedis = SpringContextHolder.getBean(JedisUtils.class).getResource(); return jedis; } /** * 释放jedis * * @return */ public static void releaseJedis(Jedis jedis) { jedis.close(); } /** * 抢占执行权 锁 * @param lockName * @param lockExpire * @return */ public static Boolean acquireRedisLock(String lockName,int lockExpire){ Jedis jedis = getJedis(); String identifier = UUID.randomUUID().toString(); String lockKey = lockName; try{ if (jedis.setnx(lockKey, identifier) == 1) { logger.info("Get lock {} success:{}.",lockName,identifier); jedis.expire(lockKey,lockExpire); if (jedis.ttl(lockKey) == -1) { jedis.expire(lockKey, lockExpire); } return true; } return false; }catch (Exception e){ logger.error(e.getMessage()); return false; }finally { if(jedis !=null){ releaseJedis(jedis); } } }}到此,相信大家对"如何用AOP注解方式实现redis分布式抢占锁"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
注解
方式
任务
方法
分布式
节点
需求
生产
内容
切面
环境
代理
处理
学习
实用
更深
事项
代码
作用
兴趣
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
西青区网络安全知识培训
网络安全过载攻击
王国纪元服务器
国铁网络安全市场容量
智慧公厕数据库
软件开发公司罚款
c语言和网络技术这些就业
网际快车键盘软件开发
网络技术考研科目
土地变更调查数据库标准下载
电信网络安全专业排名
健康管理软件开发
txt和数据库哪个读取快
四川系统软件开发排名
在数据库中如何排序
2020网络安全日题目
湖北奥盾网络安全
网络安全小达人手抄报图片
数据库局部变量前缀
网络安全 队伍建设
服务器升级中不能更换头像
南平网络技术有限公司
c创建数据库文件
esp32怎么连接别人服务器
用什么软件开发的股票
asp连接mysql数据库方法
如何禁用服务器任务管理器
软件开发属于国拨经费哪一类
恒生互联网科技业指数成分
魂师对决服务器人多进不去了咋办