干货!接口中的大事务,该如何进行优化?

作为后端开发的程序员,我们常常会的一些相对比较复杂的逻辑,比如我们需要给前端写一个调用的接口,这个接口需要进行相对比较复杂的业务逻辑操作,比如会进行,查询、远程接口或本地接口调用、更新、插入、计算等一些逻辑,将最终接口的返回结果给到前端,而经过这么一系列的业务逻辑操作,接口对DB的操作、对代码业务逻辑判断、进行接口调用这些都是需要时间的,而只要这是一个事务操作,每次对数据库进行的交互都会产生一条事务记录。

那么这样就会对我们接口返回的效率产生影响,而且这个影响是随着数据量的增长而增长的,这时候我们就需要对一整个大事务进行拆分,从而提升整体接口的效率。

何为大事务

就拿我最近开发写的一个接口来说吧,大致是这么一个逻辑,我需要根据页面的提交的数据生成一个收款单,整体接口处理的业务如下,我把它们写在了一个接口里,可以理解为这是一个大事物,这个接口执行的时间是相对比较长的,而且将这些逻辑全部写在一个接口里面,本身来说也是不太合理的。

图片

大事务存在的一些问题

并发数据不一致

不加锁的情况下,由于种种原因第一次接口的调用还没执行完,还在等待第三方的调用回写数据,第二次调用又进来对数据进行了更改,第二次调用先执行完,这时候第一次接口调用拿到了第三方接口的返回,去回写状态发现已经被更新,导致无效操作。

加锁容易阻塞

加锁的情况下, 不会出现数据不一致情况,但是由于大事物执行时间较长,容易造成锁超时失效,锁定太多的数据造成阻塞,严重影响效率。

Undo logo事务日志性能问题

容易造成Undo logo日志数据量很大,降低了日志的查询性能,包括对事务的回滚效率也会降低。

并发数据库压力太大

并发量达到一定程度,会对数据库读写造成不小的压力,会堆积大量等待线程。

如何优化大事务

事务里面不要进行远程RPC调用

首先事务里面进行远程的接口调用,如果不采用分布式事务框架,本身就会存在事务不一致的情况,无法进行数据的回滚操作,并发情况下远程服务响应不及时,会出现接口返回不一致问题,当然必须采用异步调用,后面会提到。

编程型事务更加灵活

声明式事务只需要加在方法头加@Transactional注解即可开启事务,但是还是不太灵活,意味着整个方法所进行对数据库操作都要加进事务,当然一次查询也要进入事务,这并不是我们想要的,我们在update、insert操作上进行事务操作,方便进行回滚。

public Boolean transactionCommit(String userName) {//查询用户SysUser sysUser = userMapper.selectUserByUserName(userName,null);transactionTemplate.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {try {if (null != sysUser) {//用户信息状态更新 status更新为1userMapper.updateStatus(userName);}} catch (Exception e){//回滚transactionStatus.setRollbackOnly();}}});//再次查询SysUser sysUser1 = userMapper.selectUserByUserName(userName,"1");/log/.info("状态为1的用户信息"+JSON./toJSONString/(sysUser1));return  true;
}

编程式事务的灵活点在于可以控制事务执行方法,运用transactionTemplate类进行事务操作,查询操作可以写在外面,这样查询获取数据的操作就不会进入mysql事务表。

数据分批处理

对于事务的更新或者插入,前端可能会有批量操作,大规模数据的批量更新、插入也会对事务接口产生影响,一旦其中有更新或插入失败,为了保证事务的一致性,整个操作都要进行回滚;

  • 前端:可以限制数据,对后端接口的访问,可以将数据进行分页,多次请求,可以避免事务提交大量数据。

  • 后端:也可以去数据进行分页处理,例如每次可以限制50条进行操作,如果是新增逻辑,使用Mybatis的批量更新大大提升效率

List<List<ReceivableFeeSaveDTO>> partition = Lists.partition(receivableFeeSaveDTOList, 50);

大事务拆分小事务

可以将一个事务接口,拆分成多个事务接口,并且每个事务接口只做一件事,比如上面的收款单生成接口,金额回写、第三方接口调用、调用后的结果回写都可以抽成一个哥小事务接口。

就好比做一件很复杂的事情,咋一眼看上去很复杂,但是我们把这复杂的步骤,进行多个步骤的拆分,每个阶段完成每个阶段的事情,就可以将整个过程简化,看起来就没那么复杂了。

异步并行处理

重中之重,事务里如果无法避免远程调用,那么肯定是需要进行异步调用,因为无法保证远程接口的及时响应性,CompletableFuture异步编排特性可以用到,task1和task2任务结束后,执行task3。

CompletableFuture<Object> task1 =CompletableFuture.supplyAsync(() -> {System.out.println("单号check线程" + Thread.currentThread().getId());//单号check接口 校验失败抛出异常return "账单实体信息";
}, executor);
CompletableFuture<Object> task2 = CompletableFuture.supplyAsync(() -> {System.out.println("收款单生成线程" + Thread.currentThread().getId());try {//收款单生成return “账单编号”;Thread.sleep(3000);System.out.println("任务2结束:");} catch (InterruptedException e) {e.printStackTrace();}}, executor);//task1、task2 执行完执行task3 ,需要感知task1和task2的执行结果
CompletableFuture<Boolean> future = task1.thenCombineAsync(task2, (t1, t2) -> {System.out.println("账单金额回写线程" + Thread.currentThread().getId());// t1 、t2返回判断//回写返回结果return ture;
}, executor);

总结

可见大事务是我们接口效率低下的罪魁祸首,有时候我们为了快速实现功能,可能会忽略一些关乎于性能的东西,而这些东西是我们能力提升的一个契机。

随着你的进步,你也许会有疑问之前为什么这么写代码,当你有这种感觉的时候,那么恭喜你,你已经站在另一个山岗,俯瞰山下一切都是那么的渺小,不多说我先去优化接口了~

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

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

相关文章

掌握iText:轻松处理PDF文档-进阶篇

简体中文写入 iText本身对简体中文的支持有限&#xff0c;但可以通过引入额外的字体包来增强其对简体中文的支持。例如&#xff0c;可以使用iTextAsian.jar这个亚洲字体包&#xff0c;它包含了几种简单的亚洲字体&#xff0c;其中包括简体中文字体。只需要将iTextAsian.jar放到…

46. 全排列

46. 全排列 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;_46全排列_构建数组回溯_46全排列_直接构建 错误经验吸取 原题链接&#xff1a; 46. 全排列 https://leetcode.cn/problems/permutations/description/ 完成情况&#xff1a;…

小模型学习(1)-人脸识别

【写作背景】因为最近一直在研究大模型&#xff0c;在与客户进行交流时&#xff0c;如果要将大模型的变革性能力讲清楚&#xff0c;就一定要能将AI小模型的一些原理和效果讲清楚&#xff0c;进而形成对比。当然这不是一件简单的事情&#xff0c;一方面大模型分析问题的的本质原…

反射加载SDK完成统一调用

文章目录 1、需求背景2、接口抽象类具体实现类3、疑问4、存在的问题5、通过反射加载SDK并完成调用5、补充&#xff1a;关于业务网关7、补充&#xff1a;关于SDK的开发 关键点&#xff1a; 接口抽象类&#xff08;半抽象半实现&#xff09;具体实现类业务网关反射加载SDK&#…

电脑出现这些现象,说明你的固态硬盘要坏了

与传统机械硬盘&#xff08;HDD&#xff09;相比&#xff0c;固态硬盘&#xff08;SSD&#xff09;速度更快、更稳定、功耗更低。但固态硬盘并不是完美无瑕的&#xff0c;由于颗粒写入机制&#xff0c;可能会在七到十年的预期寿命之前出现故障。所以用户最好为最终故障做好准备…

网页设计中增强现实的兴起

目录 了解增强现实 增强现实的历史背景 AR 和网页设计的交叉点 AR 在网页设计中的优势 增强参与度和互动性 个性化的用户体验 竞争优势和品牌差异化 AR 在网页设计中的用例 结论 近年来&#xff0c;增强现实已成为一股变革力量&#xff0c;重塑了我们与数字领域互动的方式。它被…

【FMCW毫米波雷达设计 】 — FMCW波形

原书&#xff1a;FMCW Radar Design 1 引言 本章研究驱动FMCW雷达的主要波形:线性调频(LFM)波形。我们研究信号的行为及其性质。随后&#xff0c;本章讨论了匹配滤波理论&#xff0c;并研究了压缩这种波形的技术&#xff0c;特别是所谓的拉伸处理&#xff0c;它赋予FMCW雷达极…

DOS 批处理 (二)

DOS 批处理 1. 基础 DOS 命令1.1 基础命令1.2 文件系统操作1.3 文件夹管理1.4 文件管理1.5 网络相关1.6 系统管理1.7 IF、FOR和NETIFFORNET 1. 基础 DOS 命令 command /? 查找帮助DOS命令不区分命令字母的大小写 C:\Users\Administrator>echo 1 1 C:\Users\Administrator…

基于SSM框架的仓库管理系统

基于SSM框架的仓库管理系统 文章目录 基于SSM框架的仓库管理系统 一.引言二.系统设计三.技术架构四.功能实现五.界面展示六.源码获取 一.引言 现代商业环境中&#xff0c;仓库管理对于企业的运营效率和客户满意度至关重要。传统的手工管理方式已经无法满足日益复杂的仓储需求。…

【Spring】SpringBoot日志

SpringBoot日志 日志概述日志使用打印日志获取日志对象使用日志对象打印日志日志框架介绍门面模式SLF4J框架介绍(simple logging facade for java) 日志格式说明日志级别日志级别的分类日志级别的使用 日志配置配置日志级别日志持久化配置日志文件的路径和文件名配置日志文件的…

【刷题篇】动态规划(六)

文章目录 1、最大子数组和2、环形子数组的最大和3、乘积最大子数组4、乘积为正数的最长子数组长度5、 等差数列划分6、最长湍流子数组 1、最大子数组和 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&…

【Unity动画】Avatar Mask

创建 Avatar Mask可以设置那一部分骨骼运动和不运动 然后放在状态机里面的层中来混合 【后续完善】

30 张图解 HTTP 常见的面试题

前言 在面试过程中&#xff0c;HTTP 被提问的概率还是比较高的 我搜集了 5 大类 HTTP 面试常问的题目&#xff0c;同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大的&#xff0c;通过问答 图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP 协议。 HTTP 基本概…

第四节JavaScript 条件语句、循环语句、break与continue语句

一、JavaScript条件语句 在通常的代码中&#xff0c;我们有一些需要决定执行不同动作&#xff0c;这就可以在代码中使用条件语句来完成。 下面是我们常使用的条件语句&#xff1a; if语句&#xff1a;只有当指定条件是true时&#xff0c;执行条件内代码。if…else语句&#…

项目二 创建与操作学生管理数据库

项目二 创建与操作学生管理数据库 #目标 创建库&#xff1b;查看库&#xff1b;操作库&#xff1b;图形工具操作库1&#xff0c;创建学生管理数据库 #创建数据库 CREATE DATABASE [IF NOT EXISTS] db_name [[DEFAULT] CHARACTER SET charset_name] [[DEFAULT] COLLATE collat…

44.0/认识前端

44.1 目录 44.1.1 网页 44.1.1.1 网页的组成 44.1.1.2 网页的分类 44.1.2 网站 44.1.2.1 网站的分类 44.1.3 主页 44.2. Internet、IP 地址和域名 44.2.1 Internet 44.2.2 IP 44.2.3 域名 44.3. Web 前端技术概述 44.3.1 html5 44.3.2 CSS3 44.3.3 Javascript …

hbuiler中使用npm安装datav

注&#xff1a;datav边框样式目前使用时&#xff1a;适用于网页&#xff0c;不适用于app 1、先安装node 安装、配置Node路径 2、为Node配置环境变量 3、在hbuilder的设置中填写node的路径 配置 4、打开cmd输入npm install jiaminghi/data-view 安装dataV&#xff0c;&…

当初为什么选择计算机-希望一直干下去

还记得当初自己为什么选择计算机&#xff1f; 当初你问我为什么选择计算机&#xff0c;我笑着回答&#xff1a;“因为我梦想成为神奇的码农&#xff01;我想像编织魔法一样编写程序&#xff0c;创造出炫酷的虚拟世界&#xff01;”谁知道&#xff0c;我刚入门的那天&#xff0…

.360勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

尊敬的读者&#xff1a; 在数字时代&#xff0c;.360勒索病毒如同数字的幽灵&#xff0c;悄无声息地侵入用户的数字领域&#xff0c;将珍贵的数据文件变为数字的囚牢。本文将介绍.360勒索病毒的特征&#xff0c;提供解密和数据恢复的方法&#xff0c;并分享有效的预防措施&…

【开源】基于JAVA语言的数字化社区网格管理系统

项目编号&#xff1a; S 042 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S042&#xff0c;文末获取源码。} 项目编号&#xff1a;S042&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、开发背景四、系统展示五、核心源码5…