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

news2024/12/23 6:10:57

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

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

2何为大事务
就拿我最近开发写的一个接口来说吧,大致是这么一个逻辑,我需要根据页面的提交的数据生成一个收款单,整体接口处理的业务如下,我把它们写在了一个接口里,可以理解为这是一个大事物,这个接口执行的时间是相对比较长的,而且将这些逻辑全部写在一个接口里面,本身来说也是不太合理的。
在这里插入图片描述
3大事务存在的一些问题
并发数据不一致
不加锁的情况下,由于种种原因第一次接口的调用还没执行完,还在等待第三方的调用回写数据,第二次调用又进来对数据进行了更改,第二次调用先执行完,这时候第一次接口调用拿到了第三方接口的返回,去回写状态发现已经被更新,导致无效操作。

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

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

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

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

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

public Boolean transactionCommit(String userName) {
    //查询用户
    SysUser sysUser = userMapper.selectUserByUserName(userName,null);

    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
            try {
                if (null != sysUser) {
                    //用户信息状态更新 status更新为1
                    userMapper.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.coloradmin.cn/o/1218151.html

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

相关文章

LabVIEW关于USRPRIO的示例代码

LabVIEW关于USRPRIO的示例代码 USRPRIO 通常以两种方式使用&#xff1a; 1 基于 FPGA 的编程 对于希望修改USRP上的底层FPGA代码以添加自定义DSP模块的应用&#xff0c;请使用USRP示例项目。它可作为构建 USRP RIO 流式处理应用程序的起点&#xff0c;可从“创建项目”对话框…

利用OpenCV做个熊猫表情包 二

之前写了一篇 利用OpenCV做个熊猫表情包吧_Leen的博客-CSDN博客 回想起来觉得有点太弱了&#xff0c;意犹未尽&#xff0c;每次使用需要自己去手动截取人脸&#xff0c;清除黑边什么的才能使用demo去合成表情&#xff0c;于是有空的时候就改进了一下&#xff0c;让它利用open…

腾讯云服务器租用价格,腾讯云服务器租用价格多少钱一年?

腾讯云服务器租用价格&#xff0c;腾讯云服务器租用价格多少钱一年&#xff1f;腾讯云服务器有优惠活动&#xff0c;现在租用只需要88元/年&#xff01;腾讯云服务器优惠购买入口&#xff1a;https://1111.mian100.cn 随着互联网的发展&#xff0c;越来越多的人开始选择将自己…

【部署篇】宝塔liunx中使用docker部署nestjs项目【全过程】

一、 &#x1f44b; 前序工作 连接服务器 获取宝塔面板信息 在命令行输入sudo /etc/init.d/bt default 进入宝塔面板输入账号密码 通过上面网址进入宝塔 安装自己需要的东西 **PS&#xff1a;**这里还需要自己登录宝塔账号&#xff0c;没有账号的同学需要注册一下 安装pm2…

Minio - 多节点多驱动器安装部署

先决条件 网络互通 MinIO集群中的节点的网络需要互相双向互通。 MinIO API默认端口9000 MinIO console默认端口9001 MinIO强烈建议使用负载均衡器来管理与集群的连接。负载均衡器策略使用“最小连接数”逻辑&#xff0c;因为在部署中任何 MinIO 节点都可以接收、路由或处理…

work环境配置

1.计算机右键找到属性 2.配置环境变量 3.新加环境变量 4.修改环境变量path .bat文件内容 php ApplicationsChatstart_register.php ApplicationsChatstart_gateway.php ApplicationsChatstart_businessworker.php pause

服务注册发现 springcloud netflix eureka

文章目录 前言角色&#xff08;三个&#xff09; 工程说明基础运行环境工程目录说明启动顺序&#xff08;建议&#xff09;&#xff1a;运行效果注册与发现中心服务消费者&#xff1a; 代码说明服务注册中心&#xff08;Register Service&#xff09;服务提供者&#xff08;Pro…

online java

在线JAVA执行器 online java 1&#xff1a;网页WEB或者客户端的文本TEX输入代码 2&#xff1a;服务端生成java文件 3&#xff1a;服务端生成class文件&#xff0c;命令javac 4&#xff1a;服务端执行class文件&#xff0c;命令java 5&#xff1a;生成结果&#xff0c;打印返回页…

基于PHP的纺织用品商城系统

有需要请加文章底部Q哦 可远程调试 基于PHP的纺织用品商城系统 一 介绍 此纺织用品商城系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。用户可注册登录&#xff0c;购物下单&#xff0c;评论等。管理员登录后台可对纺织用品&#xff0c;用户&#xf…

redis常见问题及解决方案

缓存预热 定义 缓存预热是一种优化方案&#xff0c;它可以提高用户的使用体验。 缓存预热是指在系统启动的时候&#xff0c;先把查询结果预存到缓存中&#xff0c;以便用户后面查询时可以直接从缓存中读取&#xff0c;节省用户等待时间 实现思路 把需要缓存的方法写在初始化方…

安装插件时Vscode XHR Failed 报错ERR_CERT_AUTHORITY_INVALID

安装插件时Vscode XHR Failed 报错ERR_CERT_AUTHORITY_INVALID 今天用vscode 安装python插件时报XHR failed,无法拉取应用商城的数据&#xff0c; 报的错如下&#xff1a; ERR_CERT_AUTHORITY_INVALID 翻译过来就是证书有问题 找错误代码的方法&#xff1a; 打开vscode, 按F1…

pipeline jenkins流水线

Pipeline 是 Jenkins 中一种灵活且强大的工作流机制&#xff0c;它允许您以代码的形式来定义和管理持续集成和持续交付的流程。 Pipeline 的作用主要体现在以下几个方面&#xff1a; 可编排的构建流程&#xff1a;使用 Pipeline&#xff0c;您可以将一个或多个阶段&#xff08…

小型企业网络搭建方案

在这个日益数字化和连接的世界里&#xff0c;一个稳固的小型企业网络是实现高效运作的关键支柱。不论您是在经营一家初创公司还是小型企业&#xff0c;一个可靠的企业网络都是保证顺畅沟通、数据分享以及访问在线资源的重要因素。本篇文章将会引导您完成构建一个小型企业网络的…

物联网网关在工业行业的应用案例

物联网网关在工业行业的应用案例 随着物联网技术的不断发展&#xff0c;物联网网关在工业行业的应用越来越广泛。本文将介绍一个物联网网关在工业行业的应用案例&#xff0c;以期为相关领域的研究和实践提供借鉴和启示。 一、案例背景 某大型制造企业是一家全球知名的汽车制…

Web前端—小兔鲜儿电商网站底部设计及网站中间过渡部分设计

版本说明 当前版本号[20231116]。 版本修改说明20231116初版 目录 文章目录 版本说明目录底部&#xff08;footer&#xff09;服务帮助中心版权 banner侧边栏圆点 新鲜好物&#xff08;goods&#xff09;标题 底部&#xff08;footer&#xff09; 结构&#xff1a;通栏 >…

rabbitMQ的Topic模式的生产者与消费者使用案例

topic模式 RoutingKey 按照英文单词点号多拼接规则填充。其中消费者匹配规则时候 * 代表一个单词&#xff0c;#表示多个单词 消费者C1的RoutingKey 规则按照*.orange.* 匹配 绑定队列Q1 package com.esint.rabbitmq.work05;import com.esint.rabbitmq.RabbitMQUtils; import …

关于响应式编程ReactiveX,RxGo

ReactiveX&#xff0c;简称为 Rx&#xff0c;是一个异步编程的 API。与 callback&#xff08;回调&#xff09;、promise&#xff08;JS 提供这种方式&#xff09;和 deferred&#xff08;Python 的 twisted 网络编程库就是使用这种方式&#xff09;这些异步编程方式有所不同&a…

深度学习YOLO图像视频足球和人体检测 - python opencv 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络4 Yolov5算法5 数据集6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习YOLO图像视频足球和人体检测 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非…

听GPT 讲Rust源代码--library/core/src(7)

题图来自 Hello, crustaceans.[1] File: rust/library/core/src/ptr/metadata.rs 在Rust的源代码中&#xff0c;rust/library/core/src/ptr/metadata.rs 文件的作用是定义了与指针&#xff08;ptr&#xff09;和元数据&#xff08;metadata&#xff09;相关的结构体和 trait&am…

30天黑客(网络安全)自学

前言 前几天发布了一篇 网络安全&#xff08;黑客&#xff09;自学 没想到收到了许多人的私信想要学习网安黑客技术&#xff01;却不知道从哪里开始学起&#xff01;怎么学 今天给大家分享一下&#xff0c;很多人上来就说想学习黑客&#xff0c;但是连方向都没搞清楚就开始学习…