当前位置: 首页 > news >正文

【SpringBoot】Redisson 分布式锁注解和 @Transactional 注解一起使用问题

一、前言

平时使用切面去加分布式锁,是先开启事务还是先尝试获得锁?这两者有啥区别?

业务中怎么控制切面的顺序?切面的顺序对事务的影响怎么避免?

下面程序分析:

    @Override@Transactionalpublic ReceiveH5ActivityPrizeResponse receive(ReceiveH5ActivityPrizeRequest request) {logger.info("xxx:{}", JSON.toJSONString(request));ReceiveH5ActivityPrizeResponse response=new ReceiveH5ActivityPrizeResponse();String lockName="receiveH5ActivityPrize" + request.getActivityId();final DistributeLock lock = jedisLockFactory.getJedisLock(lockName,20, TimeUnit.SECONDS);// 1.加锁lock.lock();try {//todo // 2 业务逻辑 先判断是否存在,不存在插入一条数据,存在返回(不插入)} finally {// 3.释放锁lock.unLock();}// 4 返回return response;}

分布式锁失效并不是真正的失效,只是读到数据,读取的数据库数据不是最新的。

@Transactional 注解在执行该方法时开启一个事物,当执行到3步时,insert 事物务还未提交,因此其它线程进入分布式锁代码块后,继续会执行2操作,发现数据不存在继续插入一条新数据,存在两条记录,此时数据就会出现 bug 问题。

解决办法:先加锁,然后在开启事物,可以保证安全性。 

二、普通未指定 order 的切面和 @Transactional 的先后顺序

        先说下为啥会考虑到这个,我们可以知道 @Transaction 一般加在具体要执行业务的service 方法上,那如果我要进行并发控制对业务进行加锁,那么尝试锁和开启事务孰先孰后呢?

    @Override@Transactional@RedisLock(key = Constant.FANLI_GRANT_VIP_LOCK, param = "#vipOrderNo")public void grantGdVip(String vipOrderNo) {// 业务逻辑}

        按照业务流程上来看我们需要先尝试锁后开启事务,因为没获得锁开启事务需要和数据库进行交互开启一个新的事务,平常对业务结果是不会影响的,但是当高并发时是会对数据库带来不小压力。

总结:

        如果普通切面没指定 order 会比 transaction 后执行。当锁或者一些检查性切面被使用时如果条件不满足不能进入业务也会导致事务的开启产生了不必要的消耗,当并发高时尤为明显。

三、切面的顺序对事务的影响怎么避免?

其实避免方式有三种,一种是指定order,一种是把自定义切面移到更外层中,一种是使用编程式事务。

1、指定 Order

@Aspect
@Component
@Slf4j
@Order(1)
public class LockAspect {}

2、移到最外层中

移到更外层中就不用证明了,调用的自然顺序,比如放在Controller的方法上。

    @PostMapping("/web/cardb/gift/receive")@ApiOperation("B卡赠品领取接口")@TokenAuthentication@RedisLock(key = LockKey.RECEIVE_CARD_B_GIFT, param = "#userInfo.userId")public ApiResultResponse receiveCardBGift(@RequestBody @Valid CardbReceiveGiftRequest request) {// 代码
}

3、使用编程式事务

 当然可以,调用的自然顺序,事务的开启更加现式。

四、总结

因为声明式事务比较好用,生产中使用的比较多,只有为了控制事务粒度或者不需要抽出一个新的类(为了使事务生效)才会使用编程式事务。

所以更加倾向于移到更外层,因为指定 order 的前提是你知道事务切面的和不指定order普通切面的顺序,同时一旦切面变多比如有统一加锁切面、统一检查是否认证切面等需要控制自定义切面顺序容易和事务切面搞混,不利于维护,这个也相当于自定义切面和框架前面隔离。这也从一个侧面证明了校验放 controller 的合理性。

五、参考文档

@Transactional和普通自定义切面执行顺序的思考

相关文章:

【SpringBoot】Redisson 分布式锁注解和 @Transactional 注解一起使用问题

一、前言 平时使用切面去加分布式锁,是先开启事务还是先尝试获得锁?这两者有啥区别? 业务中怎么控制切面的顺序?切面的顺序对事务的影响怎么避免? 下面程序分析: OverrideTransactionalpublic ReceiveH5…...

Druid数据库连接池框架

1.Druid概述 Druid 是一个开源的数据库连接池框架,用于管理和优化数据库连接的使用。它提供了高效的、可扩展的连接池管理,可以用于 Java 应用程序连接到关系型数据库。 之前有了解过 C3P0 数据库连接池,所谓数据库连接池就是重复利用连接数据…...

Python项目打包

Python项目如何打包? 本指南总结了Python项目打包的最佳实践,主要涉及代码的打包和分发,以及环境和依赖的管理。 0. 一般项目清单 源代码(可使用git托管)数据包(可使用DVC托管)Docker环境镜像…...

ASUS(华硕) B760M-AYW WIFI D4_解决wifi不能使用

1、最近新购买了一套 diy电脑主机,选用的是 ASUS B760M-AYW WIFI D4电脑主板 win10 系统,到货后 发现右下角电脑图标处及网络适配器中 没有wifi选项 首先 在官网和旗舰店客服处,确认了 该主板 有集成wifi模块,鲨鱼鳍天线未安装…...

Postgresql数据库运维统计信息

如果需要使用以下运维信息,需要如下几步 修改postgresql.conf文件 #shared_preload_libraries # (change requires restart)shared_preload_libraries pg_stat_statements重启数据库创建扩展 CREATE EXTENSION IF NOT EXISTS pg_stat_statements;1. 统计信息…...

Python3基础

导包 在 python 用 import 或者 from...import 来导入相应的模块。 将整个模块(somemodule)导入,格式为: import somemodule 从某个模块中导入某个函数,格式为: from somemodule import somefunction 从某个模块中导入多个函数,格式为&#…...

【性能测试】服务器常用的性能指标总结,一文概全...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 压测过程中&#…...

Vue学习笔记-Vuex基本使用

基本使用 初始化数据、配置actions、mutations,操作文件/store/index.js //index.js文件用于创建Vuex中最为核心的store对象 import Vue from vue import Vuex from vuex Vue.use(Vuex) //actions对象用于响应组件中的动作,专门负责业务逻辑 const actions {//函数…...

vue3中的customRef创建一个自定义的 ref对象

customRef 创建一个自定义的 ref&#xff0c;并对其依赖项跟踪和更新触发进行显式控制 小案例: 自定义 ref 实现 debounce <template><div style"font-size: 14px;"><input v-model"text" placeholder"搜索关键字"/><…...

动态规划学习——子序列问题

目录 ​编辑 一&#xff0c;最长定差子序列 1.题目 2&#xff0c;题目接口 3&#xff0c;解题思路及其代码 一&#xff0c;最长定差子序列 1.题目 给你一个整数数组 arr 和一个整数 difference&#xff0c;请你找出并返回 arr 中最长等差子序列的长度&#xff0c;该子序列…...

使用 COPY 加速 PostgreSQL 批量插入

文章目录 1.copy命令介紹2.copy vs insert的优势3.测量性能4.结论 1.copy命令介紹 PostgreSQL 中的命令COPY是执行批量插入和数据迁移的强大工具。它允许快速有效地将大量数据插入表中。 COPY命令为批量插入和数据迁移提供了更简单且更具成本效益的解决方案。 可以避免使用诸…...

plotneuralnet和netron结合绘制模型架构图

plotneuralnet和netron结合绘制模型架构图 一、plotneuralnet 本身的操作 模型结构图的可视化&#xff0c;能直观展示模型的结构以及各个模块之间的关系。最近借助plotneuralnet python库&#xff08;windows版&#xff09;绘制了一个网络结构图&#xff0c;有一些经验和心得…...

MYSQL 中如何导出数据?

文章目录 前言MySQL 导出数据使用 SELECT ... INTO OUTFILE 语句导出数据SELECT ... INTO OUTFILE 语句有以下属性:导出表作为原始数据导出SQL格式的数据将数据表及数据库拷贝至其他主机 后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;…...

GPT-4惨遭削弱,偷懒摸鱼绝不多写一行代码,OpenAI已介入调查

GPT-4再次遭网友“群攻”&#xff0c;原因是“懒”得离谱! 有网友想在Android系统开发一个能够与OpenAI API实时交互的应用。 于是把方法示例链接发给GPT-4&#xff0c;让它参考用Kotlin语言编写代码: 没成想&#xff0c;和GPT-4一来二去沟通半天&#xff0c;GPT-4死活给不出…...

CSS特效020:涌动的弹簧效果

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花边是描述了一些CSS…...

系列五、Spring整合MyBatis不忽略mapper接口同目录的xxxMapper.xml

一、概述 默认情况下maven要求我们将xml配置、properties配置等都放在resources目录下&#xff0c;如果我们强行将其放在java目录&#xff0c;即将xxxMapper.xml和xxxMapper接口放在同一个目录下&#xff0c;那么默认情况下maven打包时会将这个xxxMapper.xml文件忽略掉&#xf…...

第454题.四数相加II

力扣题目链接 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0 分析&#xff1a; 当需要判断一个元素是…...

RabbitMQ消息队列

简介 MQ(message queue)&#xff0c;从字面意思上看就个 FIFO 先入先出的队列&#xff0c;只不过队列中存放的内容是 message 而已&#xff0c;它是一种具有接收数据、存储数据、发送数据等功能的技术服务。 作用&#xff1a;流量削峰、应用解耦、异步处理。 生产者将消息发送…...

ModBus电表与RS485电表有哪些区别?

在能源计量领域&#xff0c;ModBus电表和RS485电表是两种常见的设备&#xff0c;它们都具有监测和记录电能数据的功能。然而&#xff0c;它们之间存在一些区别&#xff0c;比如通信协议、连接方式、数据格式等等参数的区别有哪些&#xff1f; ModBus电表和RS485电表都是用于电能…...

vue项目运行时,报错:ValidationError: webpack Dev Server Invalid Options

在运行vue项目中&#xff0c;遇到报错&#xff1a;ValidationError: webpack Dev Server Invalid Options&#xff0c;如下图截图&#xff1a; 主要由于vue.config.js配置文件错误导致的&#xff0c;具体定位到proxy配置代理不能为空&#xff0c;导致运行项目报错&#xff0c;需…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...