如何用AOP注解方式实现redis分布式抢占锁
发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,本篇内容主要讲解"如何用AOP注解方式实现redis分布式抢占锁",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何用AOP注解方式实现redis分布式抢占
千家信息网最后更新 2025年01月24日如何用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{ //获取所有需要同步状态的付款单据 ListallNeedSyncStatusForPayment = 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安全错误
数据库的锁怎样保障安全
软件开发项目流程节点
抽卡服务器早定
网络安全示范学校材料
数据库反写实时库
威海跑腿app软件开发
网络安全队长发言
邯郸web前端软件开发
app软件开发服务类合同模板
个人网络安全防范测试
南昌英语软件开发哪家好
小学生网络安全儿歌短
安全网络技术服务协议
凉山软件开发报价
图们市网络安全
怎么把服务器锁起来
四川管理系统软件开发费用
激战2有几个服务器
数据库参数查询姓氏统计
中国电信最新服务器中标
农业银行软件开发实习薪资
做网络安全产品的厂家
江西南昌有大数据库吗
现在服务器怎么配
上海网络安全宣传周什么区
数据库建设包含什么
昆山的互联网科技公司
签订网络安全公约
江苏多赢互联网科技有限公司
网络技术进步
计算机网络安全方面的法律