基于注解的方式实现分布式锁的AOP功能
使用场景:
在分布式项目中,涉及到事务,且会操作多张表,那么涉及到并发场景,应当避免同一时间有多个用户并发操作同一份数据,例如:商品秒杀。
解决方案:
使用@Around
注解实现在方法执行前后获取和释放锁的逻辑,使用Spring AOP。以下是一个完整的示例,展示如何创建一个切面(Aspect),在方法执行前后分别获取和释放分布式锁。
自定义注解
/*** <p>分布式锁:基于注解的形式使用AOP实现</p>** @author wujiada* @since 2024/12/6 17:01*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DistributedLock {// 锁名称String lockName() default "";// 1全局锁、2用户锁String rangeType() default "1";
}
编写切面类,实现获取锁和释放锁
/*** @ClassName: DistributedLockAspect* @Author: wujiada* @Date: 2024/12/6 17:03* @Description: 分布式锁切面类*/
@Aspect
@Component
@Slf4j
public class DistributedLockAspect {@Resourceprivate RedissonClient redissonClient;@Around("@annotation(com.tibiot.cloud.common.annotation.DistributedLock)")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {MethodSignature signature = (MethodSignature) joinPoint.getSignature();// 获取锁,锁的名称:业务标识前缀+LOCK,避免与其他业务冲突String lockName = getLockName(joinPoint, signature) + "LOCK";RLock clientLock = redissonClient.getLock(lockName);try {log.info("获取锁=======>{}", lockName);// 使用带有看门狗功能的锁,设置超时时间为10秒clientLock.lock(10, TimeUnit.SECONDS);// 执行业务逻辑return joinPoint.proceed();} catch (Exception e) {throw new AppRuntimeException(CODE_GENERATION_FAILURE);} finally {// 无需主动解锁,锁会在10秒后自动释放// 检查当前线程是否持有这个锁if (clientLock.isHeldByCurrentThread()) {// 如果WatchDog未生效,则需要手动解锁clientLock.unlock();log.info("释放锁=======>{}", lockName);}}}/*** <p>获取锁的名称</p>** @return {@link String}* @author wujiada* @since 2024/12/6 18:32*/private static String getLockName(ProceedingJoinPoint joinPoint, MethodSignature signature) throws NoSuchFieldException, IllegalAccessException {DistributedLock distributedLock = signature.getMethod().getAnnotation(DistributedLock.class);String lockName = distributedLock.lockName();// 因为资金划拨只是关于用户,不需要全局锁,所以锁是每个父账户一把锁,所有子用户共用父账户的锁if ("2".equals(distributedLock.rangeType())) {// 资金划拨方法需要单独处理String methodName = joinPoint.getSignature().getName();// 判断方法名if ("customerEnterpriseFundTransfer".equals(methodName)) {// 获取方法入参Object[] args = joinPoint.getArgs();// 获取参数if (args.length > 0 && args[0] != null) {// 通过反射获取字段值,也就是父账户String fieldName = "parentCode";java.lang.reflect.Field field = args[0].getClass().getDeclaredField(fieldName);// 使得私有字段也可以访问field.setAccessible(true);String fieldValue = (String) field.get(args[0]);// 拼接子账户的父账户,避免不同的子用户操作同一个父账户的资金lockName = lockName + "-" + fieldValue;}}}return lockName;}}
在方法上使用该注解
/*** <p>资金划拨</p>** @param request {@link CustomerEnterpriseFundTransferRequest}* @return {@link String}* @author wujiada* @since 2024/12/6 15:20*/@Override@Transactional(rollbackFor = Exception.class)@DistributedLock(value = "fundTransfer", type = "2")public String fundTransfer(CustomerEnterpriseFundTransferRequest request) {// 查询该子账户// 更新子账户余额// 更新父账户的余额// 保存划拨记录return "资金划拨成功";}
验证
获取锁
释放锁
相关文章:
基于注解的方式实现分布式锁的AOP功能
使用场景: 在分布式项目中,涉及到事务,且会操作多张表,那么涉及到并发场景,应当避免同一时间有多个用户并发操作同一份数据,例如:商品秒杀。 解决方案: 使用Around注解实现在方法…...
22. 五子棋小游戏
文章目录 概要整体架构流程技术名词解释技术细节小结 1. 概要 🔊 JackQiao 对 米粒 说:“今天咱们玩个五子棋小游戏,电脑与你轮流在一个 nn 的网格上放置棋子(X 或 O),网格由你输入的正整数n决定࿰…...
import是如何“占领满屏“
import是如何“占领满屏“的? 《拒绝使用模块重导(Re-export)》 模块重导是一种通用的技术。在腾讯、字节、阿里等各大厂的组件库中都有大量使用。 如:字节的arco-design组件库中的组件:github.com/arco-design… …...
传奇996_53——后端ui窗口局部刷新
描述:一个大窗口,点击某个键,弹出小窗口。 小窗口中将msg存进变量中 大窗口中判断一个参数是否为null,如果不为null,说明界面不是第一次打开,而是被刷新了。就加上小窗口的那个变量 有时小窗口中还有其他…...
云原生API网关:2024年的性能与智能化突破
API网关已经成为现代应用世界的流量控制器,并正在成为现代应用架构的重要组成部分。然而,自成立以来,他们的角色发生了巨大变化。它们正在减轻重量,变得更加可编程,并与云原生环境携手合作。 让我们来探索这一激动人心…...
专题二十五_动态规划_两个数组的 dp (含字符串数组)_算法专题详细总结
目录 动态规划_两个数组的 dp (含字符串数组) 1. 最⻓公共⼦序列(medium) 解析: 1. 状态表⽰: 2. 状态转移⽅程: 3. 初始化:编辑 4. 填表顺序:编辑 5. 返回值…...
day09 接口测试(5)——使用postman 完成项目实战
【没有所谓的运气🍬,只有绝对的努力✊】 目录 1、项目简介 2、技术栈 2.1 技术栈 2.2 技术架构图 3、初始化项目环境!!! 3.1 新建用例集 3.2 创建环境变量 3.3 登录模块 3.3.1 从测试用例文档提取数据 3.3.2…...
【Solidity】变量详解:类型、作用域与最佳实践
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 Solidity变量详解:类型、作用域与最佳实践引言1. 变量的类型与声明1…...
知识图谱9:知识图谱的展示
1、知识图谱的展示有很多工具 Neo4j Browser - - - - 浏览器版本 Neo4j Desktop - - - - 桌面版本 graphX - - - - 可以集成到Neo4j Desktop Neo4j 提供的 Neo4j Bloom 是用户友好的可视化工具,适合非技术用户直观地浏览图数据。Cypher 是其核心查询语言&#x…...
scss文件内引入其他scss文件报错
1、今天在编译一些老项目的时候,老是提示下面信息 2、而且有很多Sass import rules are deprecated and will be removed in Dart Sass 3.0.0.警告 3、用npm view sass versions看,其中sass的最新版本是1.82.0 4、经过测试"sass": "1.75…...
使用 ASP.NET Core HttpLoggingMiddleware 记录 http 请求/响应
我们发布了一个应用程序,该应用程序运行在一个相当隐蔽的 WAF 后面。他们向我们保证,他们的产品不会以任何方式干扰我们的应用程序。这是错误的。他们删除了我们几乎所有的“自定义”标头。为了“证明”这一点,我构建了一个中间件,…...
沃丰科技智能客服在跨境电商独立站中的核心角色
随着全球化进程的加速和互联网技术的不断发展,跨境电商行业蓬勃兴起,为消费者提供了更广阔、更便捷的购物选择。在这样一个竞争激烈的市场环境中,优质的客户服务成为了企业脱颖而出的关键。沃丰科技智能客服凭借其先进的技术和人性化的设计理…...
基于Springboot滑雪物品在线租赁网站设计与实现(作品+论文+开题报告)
博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育、辅导。 所有项目都配有从入门到精通的基础知识视频课程ÿ…...
android 富文本及展示更多组件
模拟微博 #热贴 和 用户 的这种 富文本形式组件,不说了, 直接上代码 package com.tongtong.feat_watch.viewimport android.content.Context import android.graphics.Color import android.util.AttributeSet import android.view.LayoutInflater impo…...
Java-JMX 组件架构即详解
JMX架构由三个主要组件构成: MBeans(Managed Beans):代表可管理的资源,是JMX的核心。MBean可以是Java类或接口,提供了管理操作的接口,如获取系统信息、设置参数等。MBeanServer&#x…...
开源轻量级文件分享服务Go File本地Docker部署与远程访问
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
Rust快速入门(五)
生命周期 生命周期的主要作用是避免悬垂引用。 这里我们详细说说借用检查: {let r; // ----------- a// |{ // |let x 5; // --- b |r &x; // | |} /…...
租赁系统|租赁小程序|租赁小程序成品
租赁系统是现代企业管理中不可缺少的数字化工具,它通过高效的信息整合与流程管理,为企业带来极大的便利和效益。一个完善的租赁系统开发应具备以下必备功能: 一、用户管理 用户管理模块负责系统的访问控制,包括用户注册、登录验证…...
后端-pageHelp分页查询
在pom.xml文件中先导入分页的坐标 PageResult里面有两个后端返回给前端的参数,我们最后把PageResult再封装到Result中, PageResult和Result都是工具类 EmployeeDTO中是前端页面中的模糊查询字段和分页的两个值 注意! 括号中的参数Employee…...
MySQL | 尚硅谷 | 第15章_存储过程与函数
MySQL笔记:第15章_存储过程与函数 文章目录 MySQL笔记:第15章_存储过程与函数第15章_存储过程与函数 1. 存储过程概述1.1 理解1.2 分类 2. 创建存储过程2.1 语法分析2.2 代码举例 3. 调用存储过程3.1 调用格式3.2 代码举例3.3 如何调试存储过程演示代码 …...
汽车零部件设计之——麦弗逊悬架KC特性分析仿真APP介绍
汽车零部件是汽车工业的基石,是构成车辆的基础元素。一辆汽车通常由上万件零部件组成,包括发动机系统、传动系统、制动系统、电子控制系统等,它们共同确保了汽车的安全、可靠性及高效运行。在汽车产业快速发展的今天,汽车零部件需…...
代码随想录-算法训练营day41(动态规划04:01背包,01背包滚动数组,分割等和子集)
第九章 动态规划part04● 01背包问题,你该了解这些! ● 01背包问题,你该了解这些! 滚动数组 ● 416. 分割等和子集 正式开始背包问题,背包问题还是挺难的,虽然大家可能看了很多背包问题模板代码…...
Vue Loader的作用
Vue Loader是一个专门用于处理Vue单文件组件(SFCs,即Single File Components)的webpack加载器(loader)。以下是Vue Loader的具体作用: 1、解析和转换Vue单文件组件 Vue Loader能够解析和转换.vue文件&…...
SRS 服务器入门:实时流媒体传输的理想选择
在当今视频流媒体需求爆炸式增长的时代,如何选择一款高效、稳定且功能强大的流媒体服务器成为了许多开发者和企业关注的焦点。而 SRS(Simple Realtime Server)作为一款开源的流媒体服务器,以其卓越的性能和灵活的功能,…...
4K高清壁纸网站推荐
1. Awesome Wallpapers 官网: https://4kwallpapers.com/ 主题: 创意、摄影、人物、动漫、绘画、视觉 分辨率: 4K Awesome Wallpapers 提供了丰富的高质量图片,分为通用、动漫、人物三大类,可以按屏幕比例和分辨率检索,满足你对壁纸的各种…...
如何保证数据库和缓存双写一致性?
数据库和缓存(redis)双写数据一致性问题再高并发的场景下,是一个很严重的问题,无论在工作中,还是面试,遇到的概率非常大,这里就聊一聊目前的常见解决方案以及最优方案。 常见方案 缓存的主要目…...
QT 多级嵌套结构体,遍历成员--半自动。<模板+宏定义>QTreeWidget树结构显示
Qt的QTreeWidget来显示嵌套结构体的成员,并以树形结构展示。 #include <QApplication> #include <QTreeWidget> #include <QTreeWidgetItem> #include <QString> #include <cstdint>// 假设这些是你的结构体定义 struct BaseMeterPa…...
《深入浅出HTTPS》读书笔记(17):公开密钥算法
公开密钥算法(Public Key Cryptography),也称为非对称加密算法(Asymmetrical Cryptography)。 公开密钥算法的功能比较多,可以进行加密解密、密钥协商、数字签名。 【密钥是一对】 公开密钥算法的密钥是一对…...
React 中为什么不直接使用 requestIdleCallback?
首先看下 requestIdleCallback是什么? 简介 requestIdleCallback 是一个在浏览器空闲时执行低优先级任务的 API。 定义与用途 requestIdleCallback 方法允许开发者在浏览器的空闲时段内调度函数的执行。这些函数通常用于执行非关键性的、低优先级的任务,…...
工作:SolidWorks从3D文件导出2D的DWG或DXF类型文件方法
工作:SolidWorks从3D文件导出2D的DWG或DXF类型文件方法 SolidWorks从3D文件导出2D的DWG或2D DXF类型文件方法(一)打开3D文件(二)从装配体到工程图(三)拖出想要的角度的图型(四&#…...
element-ui radio和checkbox禁用时不置灰还是原来不禁用时的样式
把要紧用的内容加上一个class"notEdit-page" z注意要在style里面写不能加上scoped /*//checkBox自定义禁用样式*//*//checkBox自定义禁用样式*/ .notEdit-page.el-checkbox__input.is-disabled.is-checked.el-checkbox__inner::after {border-color: #fff; } .notEdi…...
MySQL 8.0 安装与配置技术文档(Ubuntu22.04)
MySQL 8.0 安装与配置技术文档 目录 环境准备下载 MySQL 安装包检查是否已安装 MySQL彻底卸载 MySQL安装 MySQL配置 MySQL创建用户并允许外网访问修改 root 用户密码参考链接 1. 环境准备 确保系统为 Ubuntu 22.04,并安装了以下基础工具: sudo apt-ge…...
【Linux】Ubuntu中安装多个版本的gcc、g++编译器,并自由切换
1、安装 1.1 命令安装 使用命令直接安装: sudo apt install gcc-[版本号] sudo apt install g++-[版本号]例如: sudo apt install gcc-10 sudo apt install g++-10 sudo apt install gcc-9 sudo apt install g++-9 sudo apt install gcc-8 sudo apt install g++-81.2 源码…...
uni-app登录界面样式
非常简洁的登录、注册界面模板,使用uni-app编写,直接复制粘贴即可,无任何引用,全部公开。 废话不多说,代码如下: login.vue文件 <template><view class"screen"><view class"…...
如何在小米平板5上运行 deepin 23 ?
deepin 23 加入了 ARM64 支持,这里尝试将 deepin 系统刷入平板中,平常使用中,带个笔记本电脑有时候也会嫌比较麻烦,把 Linux 系统刷入平板中既满足了使用需要,又满足了轻便的需求。为什么不使用 Termux ?虽…...
Linux上的C语言编程实践
说明: 这是个人对该在Linux平台上的C语言学习网站笨办法学C上的每一个练习章节附加题的解析和回答 ex1: 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后运行它看看发生了什么。 vim ex1.c打开 ex1.c 文件。假如我们删除 return 0…...
ubuntu中使用ffmpeg库进行api调用开发
一般情况下,熟悉了ffmpeg的命令行操作,把他当成一个工具来进行编解码啥的问题不大,不过如果要把功能集成进自己的软件中,还是要调用ffmpeg的api才行。 ffmpeg的源码和外带的模块有点太多了,直接用官网别人编译好的库就…...
基于yolov8的SAR影像目标检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】
更多目标检测、图像分类识别、目标追踪等项目可看我主页其他文章 功能演示: 基于yolov8的SAR影像目标检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】_哔哩哔哩_bilibili (一)简介 基于yolov8的SAR影像目标…...
【源码】Sharding-JDBC源码分析之SQL中读写分离动态策略、数据库发现规则及DatabaseDiscoverySQLRouter路由的原理
Sharding-JDBC系列 1、Sharding-JDBC分库分表的基本使用 2、Sharding-JDBC分库分表之SpringBoot分片策略 3、Sharding-JDBC分库分表之SpringBoot主从配置 4、SpringBoot集成Sharding-JDBC-5.3.0分库分表 5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表 6、【…...
服务器卸载安装的 Node.js
卸载安装的 Node.js 版本,具体步骤取决于你是通过包管理器(如 yum 或 dnf)安装的,还是通过 nvm (Node Version Manager) 安装的。以下是针对这两种情况的指南。 通过包管理器卸载 Node.js 如果你是通过 yum 或 dnf 安装的 Node.…...
一键图片提取表格导出为Excel文档工具体验
在日常工作中,我们经常会遇到需要将图片中的表格数据转换为可编辑的Excel文件的情况。这不仅能够提高工作效率,还能减少手动输入数据的错误。本文将介绍一款实用的工具,它能够帮助我们快速实现图片到Excel的转换,同时保持操作的简…...
SpringBoot异常处理
SpringBoot异常处理 一、认识异常 异常分类: Error: 代表编译和系统错误,不允许捕获Exception: 标准Java库的方法所激发的异常,包含运行异常Runtime_Exception和非运行异常 Non_RuntimeException 的子类Runtime_Exception: 运行时异常。No…...
在 OAuth 2.0 中,refreshToken(刷新令牌)存在的意义
在 OAuth 2.0 中,refreshToken(刷新令牌) 的主要目的是为了提升用户体验和安全性,同时确保访问令牌的有效性。以下是需要使用 refreshToken 的原因: 1. 访问令牌的有限生命周期 访问令牌(accessToken&…...
【Redis】壹 —— Redis 介绍
文章目录: 前言 一、认识Redis 1. Redis 用途 作为数据库 作为流引擎 二、服务端高并发分布式结构演变 1. 单机架构 2. 应用数据分离架构 3. 应用服务集群架构 4. 读写分离 / 主从分离架构 5. 冷热分离 —— 引入缓存 6. 分库分表 7. 微服务架构 8. …...
【html网页页面010】html+css制作茶品牌文创网页制作含视频元素(7页面附效果及源码)
茶主题品牌文创网页制作 🥤1、写在前面🍧2、涉及知识🌳3、网页效果完整效果(7页):代码目录结构:page1、主页page2、精品包装page3、茶园一角page4、品牌地带page5、衍生品page6、联X我们page7、视频详情页 ἰ…...
【项目实战】基于python+爬虫的电影数据分析及可视化系统
注意:该项目只展示部分功能,如需了解,文末咨询即可。 本文目录 1.开发环境2 系统设计 2.1 设计背景2.2 设计内容 3 系统页面展示 3.1 用户页面3.2 后台页面3.3 功能展示视频 4 更多推荐5 部分功能代码 5.1 爬虫代码5.2 电影信息代码 1.开发环…...
K8S命令部署后端(流水线全自动化部署)
前言 本文为链接: 云效流水线k8s半自动部署java(保姆级)的补充,本文起初的目的是为了补充完善k8s流水线的全自动化部署,但是也适用于k8s的一键重启,因为使用k8s的web页面容易出现漏点的情况,因此也可以把代码保存为shell脚本,同样可以实现一键重启。关于…...
GPS北斗卫星授时服务器功能是什么?应用是什么?
GPS北斗卫星授时服务器功能是什么?应用是什么? GPS北斗卫星授时服务器功能是什么?应用是什么? 摘 要:首先对计算机网络时间同步相关技术进行了介绍,然后阐述了时间同步技术在现代计算机网络中的应用与发展,最后指出时间同步网络…...
学习笔记064——如何手动将jar包导入到maven本地库
文章目录 1、背景:2、方法 1、背景: 有时网络慢的情况, 本地maven库需要导入外部下载的jar包。 以便于在项目的pom文件中,直接写dependency写导入依赖。 2、方法 在Windows终端中,输入: mvn install:in…...
未来趋势系列 篇二:HBM题材解析和股票梳理
文章目录 系列文章HBM题材解析环氧塑封电镀液PSPI(光敏性聚酰亚胺)前驱体封装基板其他材料TSV技术封装测试股票梳理系列文章 未来趋势系列 篇一:AI题材解析和股票梳理 HBM HBM(High Bandwidth Memory,高带宽内存)是一种专为高效能运算设计的新兴高速内存接口技术。它通…...