jzo2o我是如何防止用户重复下单的

news/2025/4/3 3:02:20/文章来源:https://www.cnblogs.com/yzzbb/p/18805177

这里用到了aop技术 分布式锁 简单来说就是 第一个请求成功获取锁后,后续的请求会因为无法获取锁而被阻塞或直接拒绝 这很好的解决了重复提交的问题
举个很简单的例子来说 假设用户 A 快速点击了两次提交按钮。
但是管理员发现这三次请求都对应同一个钥匙(比如 "order:123"),因此只会允许第一个请求进入,后续的请求会被拒绝。
管理员就相当于是切面逻辑 这时基于注解的切点表达式 被这个注解标记的方法 切面会在方法执行前后自动处理加锁和解锁的逻辑 下面的注解不仅仅可以标记方法也可以传参 下面都是可以传进去的参数
比如说一个方法可以这样 比如说这时有两个请求A和B

@Lock(formatter = "order:{orderId}", time = 5, unit = TimeUnit.SECONDS, block = false) public void submitOrder(String orderId) { // 提交订单的逻辑 }

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

/*** 加锁key的表达式,支持表达式*/
String formatter();/*** 加锁时长*/
long time() default 5;/*** 阻塞超时时间,默认2分钟,当block为true的时候生效*/
long waitTime() default 120;/*** 加锁时间单位*/
TimeUnit unit() default TimeUnit.SECONDS;/*** 方法访问完后要不要解锁,默认自动解锁*/
boolean unlock() default true;/*** 如果设定了true将在获取锁时阻塞等待waitTime时间*/
boolean block() default false;/*** 是否启用自动续期,如果使用自动续期则unlock必须设置为true*/
boolean startDog() default false;

}
@Aspect
public class LockAspect {

private final RedissonClient redissonClient;public LockAspect(RedissonClient redissonClient) {this.redissonClient = redissonClient;
}@Around("@annotation(lock)")
public Object handleLock(ProceedingJoinPoint pjp, Lock lock) throws Throwable {//锁key的格式化字符,此字符串中有spEL表达式String formatter = lock.formatter();Method method = AspectUtils.getMethod(pjp);Object[] args = pjp.getArgs();//得到锁的keyString redisKey = AspectUtils.parse(formatter, method, args);//获取锁阻塞等待的时间,如果是0表示去尝试获取锁,如果获取不到则结束long waitTime = 0;//阻塞等待获取锁if (lock.block()) {//根据时间单位转换成mswaitTime = lock.waitTime();}//加锁时长long time = lock.time();//启动看门狗自动续期if(lock.startDog()){time = -1;//如果设置自动续期必须在方法执行后释放锁if(!lock.unlock()){throw new BadRequestException(ErrorInfo.Msg.REQUEST_PARAM_ILLEGAL);}}//得到锁对象RLock rLock = redissonClient.getLock(redisKey);//尝试加锁boolean success = rLock.tryLock(waitTime,time, lock.unit());if (!success && !lock.block()) {//未阻塞要求的情况下未得到锁throw new BadRequestException(ErrorInfo.Msg.REQUEST_OPERATE_FREQUENTLY);}if (!success) {//阻塞情况下未得到锁,请求超时throw new RequestTimeoutException(ErrorInfo.Msg.REQUEST_TIME_OUT);}try {return pjp.proceed();} finally {if (lock.unlock()) {rLock.unlock();}}}`

第一步:解析锁 key
String redisKey = AspectUtils.parse(formatter, method, args);
根据注解中的 formatter = "order:{orderId}" 和参数 orderId = 123,生成锁的 key:redisKey = "order:123"
第二步:尝试获取锁
boolean success = rLock.tryLock(waitTime, time, lock.unit());
Redis 中的分布式锁会检查是否已经有线程持有 "order:123" 这个锁。
当前没有其他线程持有这个锁,因此请求 A 成功获取了锁
第三步:执行目标方法
return pjp.proceed();
第四步释放锁
if (lock.unlock()) {
rLock.unlock();
}
这时请求B 比如说是连续点击第二下的那个订单 他也会进入进来并且解析 尝试获取锁 但这时A已经进去了 无法获取 我们设置的规则是 因为 block = false,所以请求 B 不会等待,而是直接抛出异常:
,返回错误信息:“请求过于频繁”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/909748.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

卢曼卡片盒笔记法介绍 Introduction to the Zettelkasten Method

你可能在工作中遇到了迫切需要解决的问题,可能被硕士论文压得喘不过来气,你想要提升你的博客水平,想写一本书,或者想在科研上更进一步。但是有一点需要明确,卡片盒笔记法不仅是一个帮助你完成工作或项目的工具,更是管理你生活中所遇到的知识的方法。原文链接:https://ze…

javawebDay5-Maven框架

单元测试右侧参数代表测试当前类的各项比例 Class:调用测试类中类 Method:调用方法比例 Line:调用代码量比例问题:目前猜测是用户名为中文导致

量化的前期准备

我看了不少国内量化的软件, 很多都在说QMT 迅投公司的产品, 专卖给券商, 然后券商给优质用户开 号就可以了。 各个券商的要求各不一样。 我这个因为我很多板块要求50w 存20工作日, 放了进去,居然符合券商要求了,答应给我开通了。 其实现在 很多开源的 比如easy trader 的…

[Tools] 使用 HammerDB 对 SQL Server 执行负载测试

HammerDBhttps://www.hammerdb.com/download.html HammerDB 是全球数据库行业最值得信赖的免费开源数据库基准测试应用程序,支持 Microsoft SQL Server、IBM Db2、Oracle、PostgreSQL、MariaDB 和 MySQL。HammerDB 在 Windows 和 Linux 上构建和测试,具有无与伦比的性能和可扩…

0401-git如何忽略已被版本控制的文件

前言 原因 我有很多的不关心的文件,这些都被版本控制了,我会感觉很扰乱自己的思路参考 https://www.cnblogs.com/yulinlewis/p/10236563.html 解决方法 1. 先删 git rm --cache *.pyc2. 加入.gitignore里 .gitignore文件内容 Code/.vs/ *.pyc !.gitignore效果这样就清爽多了,…

WindowsPE文件格式入门04.导入表

https://bpsend.net/thread-307-1-1.html PE 内部保存了导入的dll 和 api信息,这些信息保存到一个表里面.称为导入表, 导入表就是 记住一个可执行文件导入了那些dll,以及导入了这些dll中的哪些函数 一个可执行文件会调用其他DLL里的函数或数据,当PE文件被加载时,Windows加载器…

TODO 数据结构

先进先出(队列) 滑动窗口最大值(单调队列) 最长递增子序列(动态规划)(贪心+二分) 4.数组逆序对统计(归并排序) 快速获取集合重复值(哈希表) 6.快速获取集合最值(二叉堆) 7.无向图判环(并查集) 8.图的连通性问题(dfs+bfs)9.单源最短路dijkstra 10.多源最短路(…

CX9261S线控增益问题

简述 想将9361增益控制的逻辑移植到9261s上,先验证线控功能,配置后在接收单音信号测试中观测不到增益的变化。 配置修改 根据寄存器列表和手册修改配置的寄存器值,如图1所示。同时,修改了增益步进值为5dB。图1 手册中的控制逻辑 测试中,接收单音信号,并根据接收时钟MCLK产…

青岛oj集训5

Floyd,全源最短路,传递闭包,灾后重建,无向图的最小问题,Redistributing Gifts S,重新分发礼物 S,oj集训Floyd算法——全源最短路 cerr:标准输出错误流:不会输出到freopen制定的out文件中,而是会输出到错误文件中。 提交上去无论加不加freopen,哪怕是提交到洛谷,也只…

20244214 实验二《Python程序设计》实验报告

20244214 2024-2025-2 《Python程序设计》实验二报告 课程:《Python程序设计》 班级: 2442 姓名: 张家乐 学号:20244214 实验教师:王志强 实验日期:2025年4月1日 必修/选修: 公选课 1.实验内容 (1)设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善。…

langchain0.3教程:聊天机器人进阶之方法调用

大语言模型只能聊天吗?本篇文章将会介绍OpenAI的Function calling原理,以及在Langchain中对应的Tools Calling如何使用,最后将工具调用集成到gradio实现可视化聊天界面。我们思考一个问题:大语言模型是否能帮我们做更多的事情,比如帮我们发送邮件。默认情况下让大模型帮我…