基于redission+aop自定义分布式锁注解

Java-异步@Async方法+分布式锁自定义注解(异步方法执行完成后才释放分布式锁) 由于 joinPoint.proceed() 会立即返回,finally 块中的 lock.unlock() 也会立即执行,这会导致锁在异。确保在application.yml或application.properties中配置了Redis连接信息。确保在application.yml或application.properties中配置了Redis连接信息。在异步方法中,锁的释放不能在 finally 块中立即释放,因为 finally 块会在异步方法返回前执行。 阅读详情

基于redission+aop自定义分布式锁注解

由于我们项目中进场会用到分布式锁,所以我们定义一个注解来简化代码开发

1、常量类

/**
 * 分布式锁常量
 */
public class DistributeLockConstant {

    public static final String NONE_KEY = "NONE";

    public static final String DEFAULT_OWNER = "DEFAULT";

    public static final int DEFAULT_EXPIRE_TIME = -1;

    public static final int DEFAULT_WAIT_TIME = Integer.MAX_VALUE;
}

2、注解类

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributeLock {

    /**
     * 锁的场景
     *
     * @return
     */
    public String scene();

    /**
     * 加锁的key,优先取key(),如果没有,则取keyExpression()
     *
     * @return
     */
    public String key() default DistributeLockConstant.NONE_KEY;

    /**
     * SPEL表达式:
     * <pre>
     *     #id
     *     #insertResult.id
     * </pre>
     *
     * @return
     */
    public String keyExpression() default DistributeLockConstant.NONE_KEY;

    /**
     * 超时时间,毫秒
     * 默认情况下不设置超时时间,会自动续期
     *
     * @return
     */
    public int expireTime() default DistributeLockConstant.DEFAULT_EXPIRE_TIME;

    /**
     * 加锁等待时长,毫秒
     * 默认情况下不设置等待时长,会一直等待直到获取到锁
     * @return
     */
    public int waitTime() default DistributeLockConstant.DEFAULT_WAIT_TIME;
}

3、使用方法

@DistributeLock(keyExpression = "#telephone", scene = "USER_REGISTER")

4、核心AOP代码

@Order(Integer.MIN_VALUE)主要作用是如果多个AOP在同一个方法上,那么需要保证分布式锁的优先级最高,即@Order的value值最小

例如这种情况
@Transactional(rollbackFor = Exception.class)
@DistributeLock
如果不设置执行顺序的话,默认的顺序为

  1. 创建事务
  2. 加锁
  3. 解锁
  4. 提交事务
    如果在3,4步骤中,分布式锁已经释放锁了,但是事务还没提交,那么其他线程并发的时候又可以拿到锁对数据进行操作,会有数据安全问题。
/**
 * 分布式锁切面
 */
@Aspect
@Component
@Order(Integer.MIN_VALUE)
public class DistributeLockAspect {

    private RedissonClient redissonClient;

    public DistributeLockAspect(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    private static final Logger LOG = LoggerFactory.getLogger(DistributeLockAspect.class);

    @Around("@annotation(cn.com.lock.DistributeLock)")
    public Object process(ProceedingJoinPoint pjp) throws Exception {
        Object response = null;
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        DistributeLock distributeLock = method.getAnnotation(DistributeLock.class);
        String key = distributeLock.key();
        if (DistributeLockConstant.NONE_KEY.equals(key)) {
            if (DistributeLockConstant.NONE_KEY.equals(distributeLock.keyExpression())) {
                throw new DistributeLockException("no lock key found...");
            }
            // SPEL表达式解析
            SpelExpressionParser parser = new SpelExpressionParser();
            Expression expression = parser.parseExpression(distributeLock.keyExpression());
            EvaluationContext context = new StandardEvaluationContext();
            // 获取参数值
            Object[] args = pjp.getArgs();
            // 获取运行时参数的名称
            StandardReflectionParameterNameDiscoverer discoverer
                    = new StandardReflectionParameterNameDiscoverer();
            String[] parameterNames = discoverer.getParameterNames(method);
            // 将参数绑定到context中
            if (parameterNames != null) {
                for (int i = 0; i < parameterNames.length; i++) {
                    context.setVariable(parameterNames[i], args[i]);
                }
            }
            // 解析表达式,获取结果
            key = String.valueOf(expression.getValue(context));
        }

        String scene = distributeLock.scene();
        String lockKey = scene + "#" + key;
        int expireTime = distributeLock.expireTime();
        int waitTime = distributeLock.waitTime();
        RLock rLock = redissonClient.getLock(lockKey);
        boolean lockResult = false;
        if (waitTime == DistributeLockConstant.DEFAULT_WAIT_TIME) {
            if (expireTime == DistributeLockConstant.DEFAULT_EXPIRE_TIME) {
                LOG.info(String.format("lock for key : %s", lockKey));
                rLock.lock();
            } else {
                LOG.info(String.format("lock for key : %s , expire : %s", lockKey, expireTime));
                rLock.lock(expireTime, TimeUnit.MILLISECONDS);
            }
            lockResult = true;
        } else {
        	//设置了等待时间的情况,tryLock尝试获取锁
            if (expireTime == DistributeLockConstant.DEFAULT_EXPIRE_TIME) {
                LOG.info(String.format("try lock for key : %s , wait : %s", lockKey, waitTime));
                lockResult = rLock.tryLock(waitTime, TimeUnit.MILLISECONDS);
            } else {
            	//设置了等待时间和超时时间的情况,tryLock尝试获取锁,并设置超时时间和等待时间
                LOG.info(String.format("try lock for key : %s , expire : %s , wait : %s", lockKey, expireTime, waitTime));
                lockResult = rLock.tryLock(waitTime, expireTime, TimeUnit.MILLISECONDS);
            }
        }
        if (!lockResult) {
            LOG.warn(String.format("lock failed for key : %s , expire : %s", lockKey, expireTime));
            throw new DistributeLockException("acquire lock failed... key : " + lockKey);
        }

        try {
            LOG.info(String.format("lock success for key : %s , expire : %s", lockKey, expireTime));
            response = pjp.proceed();
        } catch (Throwable e) {
            throw new Exception(e);
        } finally {
            rLock.unlock();
            LOG.info(String.format("unlock for key : %s , expire : %s", lockKey, expireTime));
        }
        return response;
    }
}

5、异常类

/**
 * 分布式锁异常类
 */
public class DistributeLockException extends RuntimeException {

    public DistributeLockException() {
    }

    public DistributeLockException(String message) {
        super(message);
    }

    public DistributeLockException(String message, Throwable cause) {
        super(message, cause);
    }

    public DistributeLockException(Throwable cause) {
        super(cause);
    }

    public DistributeLockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}
Java注解如何基于Redission实现分布式锁 主要介绍了Java注解如何基于Redission实现分布式锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 立即下载

相关推荐

SpringBoot集成Redisson实现分布式锁的方法示例

主要介绍了SpringBoot集成Redisson实现分布式锁的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

基于Redission实现分布式锁(注解版)

起两个或者更多的服务实例,操作同一个数据库(比如扣库存),然后通过nginx将这些服务实例进行负载均衡配置,通过jmeter或者其他压力测试工具实现并发访问,比较Service方法上加@Dislock和不加的区别。我们想通过注解方式无感实现分布式锁,必须要用到AOP的功能,而且是环绕通知(有do 有 return)生成lockKey,保证锁定资源的唯一性,并且只能解锁自己加的锁。主要是将RedissonClient与Redis数据库关联起来。

长沙老码农 2422

语义分割系列7-Attention Unet(pytorch实现)

本文介绍了AttentionUnet模型和其主要中心思想,并在pytorch框架上构建了Attention Unet模型,构建了Attention gate模块,在数据集Camvid上进行复现。

yumaomi的博客 2万+

Spring Boot 集成 Redisson分布式锁(注解版)

在 Spring Boot 应用程序中使用 Redisson 可以方便地实现分布式应用程序的某些方面,例如分布式锁、分布式集合、分布式事件发布和订阅等。本篇是一个使用 Redisson 实现分布式锁的详细示例,在这个示例中,我们定义了DistributedLock注解,它可以标注在方法上,配合DistributedLockAspect切面以及IDistributedLock分布式锁封装的接口,来实现redisson 分布式锁的 API 调用。

Ascend1977的博客 1万+

OS实验xv6 6.S081 开坑

OS实验xv6 6.S081 开坑 终于把xv6 2019 6.S081做完了,网络部分没有写,因为有计网实验了。怎么说呢,xv6的坑有点多,能做完多亏了:和我同学ljj交流,参考RedemptionC老哥的博客(他写的非常详细,遗憾的是,他好像没有写mmap),再者就是参考这位老哥的做法(没有源码,写得不是特别详细,不过有借鉴作用,mmap就是借鉴了他的思想)……废话不多说了,直接开始。 实验指导 首推RedemptionC的博客 这位老哥的个人博客 xv6 6.S081官网(后面的实验都要参考官网

不定期更新系统使用、编程小技巧,哔哩哔哩账号:https://space.bilibili.com/399455629,欢迎关注 4493

Unity中实现HLS视频加密与流式播放的完整方案

本文详细介绍了在Unity中实现HLS视频加密与流式播放的完整方案。针对Unity原生VideoPlayer无法直接支持实时解密的问题,提出了基于HLS协议与AES-128加密的成熟解决方案,并重点阐述了如何利用AVPro Video插件进行集成。文章涵盖了从密钥生成、使用FFmpeg进行视频加密切片,到在Unity中动态加载密钥并播放加密流的全流程,为保护付费课程、独家动画等视频内容提供了安全且高效的实践路径。

weixin_29290963的博客 393

【Redisson】基于自定义注解的Redisson分布式锁实现

在项目中,经常需要使用Redisson分布式锁来保证并发操作的安全性。在未引入基于注解的分布式锁之前,我们需要手动编写获取锁、判断锁、释放锁的逻辑,导致代码重复且冗长。为了简化这一过程,我们引入了基于注解的分布式锁,通过一个注解就可以实现获取锁、判断锁、处理完成后释放锁的逻辑。这样可以大大简化代码,提高开发效率。

Java全栈开发者 2173

电池管理系统(BMS)软件:CATL BMS二次开发_(1).CATL BMS软件概述

CATL BMS软件的保护机制是确保电池组安全和可靠运行的关键部分。通过高精度的传感器和智能算法,BMS可以实时监测电池组的状态,及时采取保护措施。二次开发中,可以根据特定的应用需求,增加新的传感器、优化算法、扩展通信接口等,进一步提高系统的性能和可靠性。维护和扩展则是确保系统长期稳定运行的重要手段。希望以上内容对您理解CATL BMS软件的保护机制有所帮助。如果您有任何进一步的问题或需要更详细的解释,欢迎随时提问。

zhubeibei168的博客 1457

Java使用redission分布式锁--注解方式

*** @return/*** 是否开启开门狗 开启看门狗后leaseTime默认为30秒,也可自己配置时间* 开启看门狗后,只要占锁成功,就会启动一个定时任务【重新给锁设置过期时间,新的过期时间就是看门狗的默认时间】,每隔10秒都会自动再续成30秒* @return/*** 重试时间(重试获取锁自旋时间)* @return/*** 锁的有效时间* @return/**

weixin_43969830的博客 720

prplOS amx-fxgi调试-订阅subscribe

本文分析了prplOS中amx-fxgi订阅功能(subscribe)的实现与调试过程。通过梳理订阅流程发现,默认订阅失败主要由于acl规则限制导致。文章详细介绍了订阅的两个关键步骤:建立GET长连接和POST设置订阅路径,并通过修改代码绕过acl验证成功实现订阅功能。最终验证了在同一连接下订阅多个路径及实时接收状态更新的可行性,有效降低了设备查询负载。该方案为prplOS的实时数据监控提供了优化思路。

四儿家的小祖宗的博客 330

2026 最新安全 Skill 合集(CTF / 审计 / 渗透 / 红队)威胁建模一网打尽

2026年安全领域进入"Skill化"时代,各类安全能力被结构化封装为可复用的AI Skill。本文介绍了7个核心安全Skill项目:渗透测试全流程的AgentSkillsHub、CTF解题技能库ctfskills、多语言代码审计工具codeaudit、PHP专项审计系统、Java自动化审计流水线、威胁建模工具threatmodeling以及覆盖30+领域的Anthropic-Cybersecurity-Skills。这些项目将传统安全经验转化为标准化、可验证、可自动执行的模块化能力,支

Chengbei11的博客 1870

注解方式优雅实现Redission

通常我们都会将redisson实例注入到方法类里面,然后调用加锁方法进行加锁,如果其他业务方法也需要加锁执行,将会产生很多重复代码,由此采用AOP切面的方式,只需要通过注解的方式就能将方法进行加锁处理。@Inherited​​​String errorDesc() default "系统正常处理,请稍后提交";​分布式锁的使用场景还是需要多注意下,根据业务场景来,并发量不大的情况下,其实没有必要加,可能在移动端操作比较频繁的情况下需要注意并发,切勿不要盲目加锁,多少会影响一些性能。

weixin_47969982的博客 638

抖音 X-Gorgon 加密算法逆向与 Python 爬虫实战(2026 最新版)

抖音(TikTok 国内版)作为日活超 8 亿的超级 App,其反爬体系在国内互联网中属于顶级难度。核心签名参数X-Gorgon和X-Khronos是几乎所有业务接口(视频详情、评论、搜索、用户主页)的“通行证”。没有正确的 Gorgon 签名,服务器直接返回403或。市面上的教程大多停留在2023 年之前的 V4 版本,而抖音在 2025 年底全面升级到了V6 协议,算法结构、加密常数、混淆方式全部重构。

2201_76125261的博客 349

【SpringBoot实战系列】从AOP+自定义注解到redission分布式锁-接口防重提交场景设计实战

自定义注解 分布式锁 aop

chandfy的博客 1759

钉钉多维表格开发

从0到1完成钉钉多维表格开发SDK对接与实践案例。

沉修所长,勇逐新机;安而不怠,静而思变 3610

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

一篇讲透Redission分布式锁

快速高效实现一把灵活的分布式锁

A161161的博客 1214

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

redission java_Java注解如何基于Redission实现分布式锁

这篇文章主要介绍了Java注解如何基于Redission实现分布式锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下1、定义注解类@Target({ ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface DistributedLock...

weixin_35308269的博客 353

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SpringBoot自定义注解 + AOP 防止重复提交

今天我们来看看如何通过AOP来防止重复提交Java核心知识-自定义注解(先了解下什么是自定义注解)Annotation(注解)从JDK 1.5开始, Java增加了对元数据(MetaData)的支持,也就是Annotation(注解)。注解其实就是代码里的特殊标记,它用于替代配置文件,常见的很多,有@Override等什么是元注解元注解是注解的注解,比如当我们需要自定义注解时会需要一些元注解(meta-annotation),如@Target和@Retentionjava内置4种元注解。

qq_27971677的博客 375

封装自定义的Starter,Gradle发布本地仓库

准备: springVersion = “5.1.13.RELEASE” springBootVersion = “2.1.12.RELEASE” gradle:gradle-5.2.1 新增一个gradle 这里我们计划实现一个基于Redission分布式锁的AOP功能。 定义一个注解 /** * prefix+value = lock * @author xqj */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME

xieqj_0511的博客 792

多人同时导出 Excel 优化

多人同时导出 Excel 优化

weixin_44739106的博客 295

SpringBoot接口防抖(防重复提交)

防抖也即防重复提交,那么如何确定两次接口就是重复的呢?首先,我们需要给这两次接口的调用加一个时间间隔,大于这个时间间隔的一定不是重复提交;其次,两次请求提交的参数比对,不一定要全部参数,选择标识性强的参数即可;最后,如果想做的更好一点,还可以加一个请求地址的对比。

记得开心一点嘛的博客 1361

海量数据处理商用短链接生成器平台 - 9

简介: 冗余双写架构-短链服务开发总结短链服务器CRUD冗余双写架构异常队列最终一致性简介: 流量包商品服务-数据库表介绍数据库表介绍`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '商品标题',

weixin_41544125的博客 1017

自定义注解 + AOP + Redisson:优雅实现分布式锁(增强版)

分布式锁是一种在分布式系统中用于控制多个进程或线程对共享资源访问的机制。互斥性:同一时刻只有一个客户端可以持有锁。可重入性:同一个客户端可以多次获取同一把锁。高可用性:锁服务需要具备高可用性,避免单点故障。自动释放:锁需要支持超时自动释放,避免死锁。定义一个注解// 锁的key,支持SpEL表达式 long waitTime() default 30;// 获取锁的最大等待时间(秒) long leaseTime() default 10;// 锁的持有时间(秒) }

双非二本自学到互联网公司的成长经历,有故事,有干货。 1522

使用自定义注解+AOP切面+Redisson实现分布式锁

/声明注解用在方法中,不能在类中使用//定义注解的保留时间,RUNTIME代表程序运行时//@interface 说明注解/*** 锁类型策略*//*** 锁键表达式(当scope=METHOD时使用)*//*** 用户ID表达式(当scope=USER_RESOURCE时使用)*//*** 锁的过期时间(秒)* 默认30秒*//*** 等待锁的最长时间(秒)* 默认5秒*//*** 锁失败时的错误信息*/

weixin_62993406的博客 411

使用Redission和Aop以及注解实现接口幂等性

本文将使用分布式锁来解决接口幂等性问题

Codewarning 1438

Redis 实现分布式锁注解 及 Redission应用

使用 Redis 实现分布式锁注解(Redission) 写在前面 本文使用 Redission 实现的分布式锁,通过注解的方式应用,避免了对业务代码的侵入。 重要文件解释 AnnotationResolver.java : 注解解析器,参考了注解实现aop、aop动态传参、使用注解aop优化代码的文章实现,可以在注解上取得参数变量 DistributedLock.java : 声明注解 DistributedLockAop.java : 分布式锁实现 RedissionConfig.java : Red

小小柯 1469
上一篇: 基于Lua+Redis实现库存的秒杀扣减
下一篇: 基于 Redis + Caffeine 做多级缓存
AllowM
博客等级 码龄7年 111粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值