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

前言

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

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

何为大事务

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

图片

 

大事务存在的一些

最近收集了一份史上最全架构师路线图,点击《史上最全架构师知识图谱》可免费获取,无任何套路。

并发数据不一致

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

加锁容易阻塞

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

Undo logo事务日志性能问题

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

并发数据库压力太大

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

插播一条:如果你近期准备面试跳槽,建议在Java面试库小程序在线刷题,涵盖 2000+ 道 Java 面试题,几乎覆盖了所有主流技术面试题。

如何优化大事务

事务里面不要进行远程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事务表。

推荐一个开源免费的 Spring Boot 实战项目:

https://github.com/javastacks/spring-boot-best-practice

数据分批处理

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

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

  • 后端:也可以去数据进行分页处理,例如每次可以限制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/182320.shtml

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

相关文章

解决msvcr71.dll丢失5个方法,修复程序运行缺失dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcr71.dll丢失”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;给使用者带来了很大的困扰。那么&#xff0c;究竟是什么原因导致了msvcr71.dll文件的丢失呢&#xff1f;本文…

什么是海外私人IP代理?是纯净独享的代理吗?

相信许多互联网工作者都遇到过IP禁令&#xff0c;比如网络抓取项目&#xff0c;使用共享代理服务器向网站发出第一个请求&#xff0c;但却您收到了禁令&#xff0c;这大部分是由于你的共享IP经过多人使用被禁用所致。 那么到底什么是私人代理呢&#xff1f;它们是否适合您的情…

微服务实战系列之Redis(cache)

前言 云淡天高&#xff0c;落木萧萧&#xff0c;一阵西北风掠过&#xff0c;似寒刀。冬天渐渐变得更名副其实了。“暖冬”的说法有点言过其实了。——碎碎念 微服务实战系列之Cache微服务实战系列之Nginx&#xff08;技巧篇&#xff09;微服务实战系列之Nginx微服务实战系列之F…

【VScode】代码文件注释,User snippets 配置 Python/C++ , 其他语言类似

在代码文件头部&#xff0c;输入 header &#xff0c;回车&#xff0c;自动生成文件注释 Python {"HEADER": {"prefix": "header","body": ["# -*- encoding: utf-8 -*-", "\"\"\"","Date …

OKCC 客户中心

OKCC服务了这么多家客户中心&#xff0c;但很多小伙伴们其实并不是太了解客户中心的主要功能&#xff0c;那么我今天将从两类客户中心介绍下他们的主要功能。 一、 运营机构客户中心的功能 对于运营机构而言&#xff0c;客户中心的功能包括:能够帮助运营机构提升品牌形象&…

set与map

set与map 一、序列式容器与关联式容器二、pair1、键值对2、作用3、构造函数4、make_pair&#xff08;1&#xff09;构造函数&#xff08;2&#xff09;作用 5、代码6、运行结果 三、set1、概念2、代码3、运行结果4、说明 四、multiset1、与set的关系2、代码3、运行结果 五、map…

Python异常处理:try语句的应用与技巧

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 异常处理在Python中是至关重要的。try-except是用于捕获和处理异常的核心机制之一。让我们深入了解如何使用try-except&#xff0c;处理各种异常情况。 try-except语句 在编程中&#xff0c;异常是指运行时发生…

Linux系统-----进程管理(进程的创建与控制)

目录 前言 进程 1.基本概念 2.特征 3.Linux系统的进程 进程的创建 1. fork()函数 2. 多进程的创建与输出 进程的控制 1. exec()系列 2. wait() 函数 3. execl( )和fork( )联合使用 4. exit&#xff08; &#xff09; 前言 前面我们学习了Linux系统的基本指令以及如…

振南技术干货集:各大平台串口调试软件大赏(1)

注解目录 &#xff08;串口的重要性不言而喻。为什么很多平台把串口称为 tty&#xff0c;比如 Linux、MacOS 等等&#xff0c;振南告诉你。&#xff09; 1、各平台上的串口调试软件 1.1Windows 1.1.1 STCISP &#xff08;感谢 STC 姚老板设计出 STCISP 这个软件。&#xf…

C语言进阶指南(16)(自定义数据类型——结构体)

欢迎来到博主的专栏——C语言进阶指南 博主id&#xff1a;reverie.ly 文章目录 结构体类型结构体类型的声明结构体变量的声明 结构体变量的初始化结构体变量结构体变量的赋值结构体变量的成员结构体变量的使用结构体变量的内存存储 前面使用的变量都是简单类型的变量&#xff0…

浅学指针(3)

系列文章目录 文章目录 系列文章目录前言系列文章目录前言1. 字符指针变量2. 数组指针变量那数组指针变量应该是&#xff1a;存放的应该是数组的地址&#xff0c;能够指向数组的指针变量。2.2 数组指针变量怎么初始化总结&#xff1a;函数名就是地址&#xff0c;&函数名和直…

Debian arm系统安装wxPython

一、系统版本 二、安装wxPython-4.0.4.tar.gz 1、下载依赖 >sudo apt update >sudo apt-get install build-essential libgtk-3-dev libwebkit2gtk-4.0-dev libssl-dev libcurl4-openssl-dev libgstreamer-plugins-base1.0-dev libnotify-dev freeglut3 freeglut3-dev …

openGauss学习笔记-134 openGauss 数据库运维-例行维护-检查操作系统参数

文章目录 openGauss学习笔记-134 openGauss 数据库运维-例行维护-检查操作系统参数134.1 检查办法134.2 异常处理 openGauss学习笔记-134 openGauss 数据库运维-例行维护-检查操作系统参数 134.1 检查办法 通过openGauss提供的gs_checkos工具可以完成操作系统状态检查。 前提…

C语言——实现一个计算m~n(m<n)之间所有整数的和的简单函数。

#include <stdio.h>int sum(int m, int n) {int i;int sum 0;for ( i m; i <n; i){sum i;}return sum;}int main() { int m, n;printf("输入m和n&#xff1a;\n");scanf("%d,%d", &m, &n);printf("sum %d\n", sum(m, n)…

Windows 11的新功能不适用于所有人,但对将要使用的人来说非常酷

正如一个新的预览版本所示&#xff0c;Windows 11即将为那些使用手写笔的人添加一些智能功能&#xff0c;以及其他改进。 这是预览版22635.2776&#xff08;也称为KB5032292&#xff09;&#xff0c;已推出Beta频道&#xff0c;这是发布预览版之前的最后一个测试方法&#xff…

一文概括AxureRP的优缺点和替代软件

AxureRP是目前流行的设计精美的用户界面和交互软件。AxureRP根据其应用领域提供了一组丰富的UI控制。 Axure是什么软件&#xff1f; Axure是目前流行的设计精美的用户界面和交互软件。Axure已经存在了近十年&#xff0c;让UX设计师轻松了解创建软件原型的细节。作为一种原型设…

zabbix 6.0 原理与部署

一、zabbix简介&#xff1a; zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 zabbix 能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 zabbi…

最佳软件配置管理工具(16款SCM工具)

配置管理&#xff08;CM&#xff09;是一种系统工程方法&#xff0c;用于在产品的整个生命周期内建立和维持产品的性能&#xff0c;功能和物理属性与其设计&#xff0c;要求和操作信息的一致性。 它们为您的组织带来了成本效益和更好的时间管理。 当今市场充斥着各种配置管理工…

天鹅湖国家旅游度假区 | 展柜OLED透明屏:创新展示提升互动体验

天鹅湖国家旅游度假区 | 展柜OLED透明屏 产品&#xff1a;一块55寸OLED透明屏嵌入玻璃安装 应用场景&#xff1a;用在天鹅湖国家旅游度假区——三门峡城市文化客厅展馆中的一个透明展示柜&#xff0c;用一块55寸OLED透明屏嵌入展示柜的玻璃&#xff0c;让观众即可以看到展柜里…

自定义注解的定义及使用场景

文章目录 1. 自定义注解如何使用2. 自定义注解使用场景2.1 自定义注解使用AOP做权限校验2.2 自定义注解使用AOP记录用户操作日志2.3 自定义注解使用AOP记录接口请求时长 1. 自定义注解如何使用 需要使用interface修饰&#xff0c;加上三个元注解 Documented&#xff1a;生成API…