使用FastExcel时的单个和批量插入的问题

在我们用excel表进行插入导出的时候,通常使用easyexcel或者FastExcel,而fastexcel是easy的升级版本,今天我们就对使用FastExcel时往数据库插入数据的业务场景做出一个详细的剖析

场景1

现在我们数据库有一张组织表,组织表的字段如下

package com.example.tabledemo.pojo.entity;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.tabledemo.pojo.BaseEntity;
import lombok.Data;/*** @Author: wyz* @Date: 2025-03-25-10:18* @Description:*/
@TableName("organization")
@Data
public class OrganizationEntity extends BaseEntity {/*** 组织代码* <p>* 组织的唯一代码,用于标识不同的组织,不能为空。* </p>*/@TableField("org_code")private String orgCode;/*** 学院/组织名称* <p>* 组织的名称,用于描述组织的具体名称,不能为空。* </p>*/@TableField("org_name")private String orgName;/*** 组织类型* <p>* 组织的类型,用于描述组织的分类或性质,可以为空。* </p>*/@TableField("org_type")private String orgType;
}

现在我们业务要求是,组织code和组织name在插入的过程中是唯一性,也就是说这两个字段的数据是唯一的,那我们对这种情况有两种处理方式

方式1

我们应该最先想到的是在业务层进行重复值的判断,具体的流程如下

 然后我们按照此流程进行插入,但是这样会出现一个典型的多线程问题,就是我再查询结束之后,进行插入的时候,有另外一个线程也插入了,这时候我又插入成功,不是出现了问题,那么解决这个问题的方法也很简单,对资源上锁就行了

方式2

我们为org_name 和org_code分别在数据库中设置一个唯一性约束

create table organization
(id          bigint auto_increment comment '序号,主键,自增'primary key,org_code    varchar(50)                        not null comment '组织代码',org_name    varchar(100)                       not null comment '学院/组织名称',org_type    varchar(50)                        null comment '类型',status      int      default 0                 null comment '状态,默认为0(可用)',create_time datetime default CURRENT_TIMESTAMP null comment '创建时间,插入时自动填充',update_time datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间,插入和更新时自动填充',is_deleted  int      default 0                 null comment '逻辑删除标志,0表示未删除,1表示已删除',constraint org_codeunique (org_code),constraint org_nameunique (org_name)
)comment '组织信息表';

这样的话,在我们后台我们只需要关注插入的问题就行了,甚至修改的时候都不需要关心数据重复性的问题,因为在mysql底层,他会为每一个设置唯一性约束的字段创建一个索引,索引是b+树结构的,每次插入的时候会查询是否有这个索引,没有就插入,有就会报错

对应的java代码如下,我们不需要加事务是因为 这是对单表进行的纯插入删除操作,无需回滚,插入不成功我们数据库有唯一性约束数据库会自动禁止插入,而且在 mybatisplus的saveOrupdate方法中也有事务管理

   @Override
//    @Transactional(rollbackFor = Exception.class)无需事务public Result add(OrganizationRequest.addOrganization addOrganization) {OrganizationEntity organizationEntity = new OrganizationEntity();BeanUtil.copyProperties(addOrganization,organizationEntity);try {boolean b = saveOrUpdate(organizationEntity);return  Result.success(b);}catch (Exception e){if (e.getCause() instanceof SQLException) {SQLException sqlException = (SQLException) e.getCause();if (sqlException.getErrorCode() == 1062) { // MySQL 唯一性约束错误码return  Result.fail("组织名称或代码已存在,请勿重复插入!");}}return  Result.fail("数据库操作失败:" + e.getMessage());}}

问题1

当我们组织表信息量大了以后,我们每一次数据的插入都会使得mysql底层的索引的b+树结构改变,这种IO带来的开销无疑是越来越大的,所以,根据这个延申出来的解决方案也有几种

对mysql进行分库分表,然后让name和code做一次hash,根据不同的hash找到不同的表,然后进行数据的插入等这样能减少重建索引带来的IO开销。但是无论是哪种方法,都有一定的优缺点,看我们如何选择了吧

场景二

现在做的是一个excel表,我们填充完数据之后,需要批量导入,这时候org_name 和org_code也是需要唯一的,同样的也有两种方式,就是我们上文所说的,只是问题从 单个插入变成了批量插入。

而批量插入在数据库中的事务也同样延申出来的许多的问题

问题1

我在使用数据库 原始的sql进行批量插入的时候,假如有3条数据ABC,B数据和C数据一样,这时候如果我加了唯一性约束,会不会导致A插入成功,B,C两条数据没有插入成功下面我们来测试一下

我们现在拿到的是最新的数据

我们插入一下看看

我们再次查询一下数据库看一下

数据并没有变化,说明了在我们用values的时候,如果加了唯一性约束,这些批量插入的后面是同一个事务的,只要有一个失败,就会回滚所有的数据。

那我们再看同一个事务下,三条数据分批次插入的情况

显而易见,分批次插入的话,只有出现异常的数据不会被插入。

那么我们再来分析,假如说 现在 我们批量插入上面三条数据,那么第一条成功了,那么第二条还没有插入的时候,这时候这个字段的唯一索引变化是怎么样的,这时候唯一索引会带来额外的额外的io开销吗?

我们看下面一张图

我是按照红字的顺序进行事务的数据插入操作的,当我进行到4的时候,我5没有提交事务,这时候4会一直阻塞,原因是 REPEATABLE READ 隔离级别下,事务会持有插入的行的排他锁(X Lock),直到事务提交或回滚。  

我们再回来看索引的问题,当我们事务没有提交的时候,也就是步骤进行到3的时候,其实mysql已经为我们插入的这条数据加了唯一性索引了,假如这时候出现了异常,导致了事务回滚,那么索引就会重新取消,这也时带来io开销

其实解决情况已经很明了了,如果不想让数据库有多的索引的io开销,那么我们就要在代码层面控制,先查询所有数据,然后比对唯一性,要么就是 数据库层面控制,

如果是在数据库层面控制,要注意 插入的时候不要用for循环单条插入,而是saveBacth批量插入,如果非用for循环单挑插入,记得使用spring的事务注解,就跟我们前面说的一样,如果是设计多条数据的改变,而且需要回滚所有,这时候记得加事务

    @Override
//    @Transactional(rollbackFor = Exception.class)public void doAfterAllAnalysed(AnalysisContext context) {log.info("所有数据解析完成!");// 字段唯一性约束 可以 用mysql 自己的 也可用 代码逻辑判断List<OrganizationEntity> organizationEntities = BeanUtil.copyToList(list, OrganizationEntity.class);
//                    boolean b = organizationService.saveBatch(organizationEntities);
//            log.info("保存成功");try {boolean b = organizationService.saveBatch(organizationEntities);log.info("保存成功");}catch (Exception e){if (e.getCause() instanceof SQLException) {SQLException sqlException = (SQLException) e.getCause();if (sqlException.getErrorCode() == 1062) { // MySQL 唯一性约束错误码throw  new RuntimeException("组织名称或代码已存在,请勿重复插入!");}}throw  new RuntimeException("数据库操作失败:" + e.getMessage());}}

而在我的代码中为什么我把事务注解注释掉了,因为再mybatisplus中,他的saveBatch方法默认加了事务

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

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

相关文章

【力扣刷题|第十七天】0-1 背包 完全背包

目标和 力扣题目网址:目标和 这道题我们先用回溯的思想来做。首先我们设正数和为S&#xff0c;数组和为N&#xff0c;目标值为T&#xff0c;那么S-(N-S)T化简之后可以得S(TN)/2即选择的正数个数为偶数&#xff0c;而且NT也为偶数&#xff0c;那么第一个判断条件我们就有了&…

深入浅出 Embedding

1. 什么是 Embedding? Embedding(嵌入)是一种将高维数据映射到低维连续空间的技术,用于表达数据的语义关系。简单来说,它是一种向量化表示,将文本、图像、用户行为等信息转换为数值向量,使得相似的数据在向量空间中距离更近。 2. 如何理解 Embedding? 2.1 浅显易懂的…

【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft Fabric 服务器搭建,Fabric 模组详细搭建教程

【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft Fabric 服务器搭建&#xff0c;Fabric 模组详细搭建教程 一、 服务器介绍二、安装 JDK 21三、搭建 Minecraft 服务端四、本地测试连接五、如何添加模组&#xff08;mods&#xff09;六、添加服务&#xff0c;并设置开…

【MLP-BEV(10)】BEVPooling V1和BEVPooling V2的view_transformer,进行鱼眼图片实践

文章目录 先说说 BEVPoolv1步骤1:3D点生成步骤2 2D特征采样和BEV特征生成特点再谈谈BEVPoolv2步骤1:3D点生成步骤2: 计算索引关系步骤3: `voxel_pooling`计算鱼眼图片进行实践步骤1、3D点生成(基于Kannala-Brandt 进行调整)步骤2、2D特征采样和BEV特征生成(1) 体素化 (Voxe…

鸿蒙项目源码-天气预报app-原创!原创!原创!

鸿蒙天气预报项目源码包运行成功含文档ArkTS语言。 我半个月写的原创作品&#xff0c;请尊重原创。 原创作品&#xff0c;盗版必究&#xff01;&#xff01;&#xff01;&#xff01; 原创作品&#xff0c;盗版必究&#xff01;&#xff01;&#xff01;&#xff01; 原创作品…

告别桌面杂乱与充电焦虑,移速165W百变桌面充电站首发体验

告别桌面杂乱与充电焦虑&#xff0c;移速165W百变桌面充电站首发体验 哈喽小伙伴们好&#xff0c;我是Stark-C~ 先如今&#xff0c;家里的电子产品越来越多&#xff0c;手机、平板、电脑三件套已经是基础配置&#xff0c;还有相机、Switch、智能手表等&#xff0c;这些产品用…

skill插件教程——skill程序的组成以及调用方法

skill程序的基本组成 1、基础的程序文件 插件运行的基础——就是你写程序的文件&#xff0c;格式为il文件&#xff0c;就是文本文件格式 2、调用程序的文件——allegro.ilint 文件申明在那个位置——在这个文件夹下&#xff0c;写入你调用的函数。 例如load&#xff08;“…

解决Dubbo3调用Springcloud接口报No provider available from registry RegistryDirectory

解决Dubbo调用Springcloud接口报No provider available from registry RegistryDirectory 问题发现问题解决 问题发现 在学习Dubbo过程中&#xff0c;Dubbo官网有一篇文章《微服务最佳实践&#xff0c;零改造实现 Spring Cloud & Apache Dubbo 互通》&#xff0c;跟着示例…

基于RFID技术建筑物资材料智能管理解决方案

建筑行业仓库和物资材料管理面临诸多挑战&#xff0c;如工程设备重复利用的管理需求、物资出入库管理不规范、账物不符、物资丢失等问题。特别是在复杂多变的工地环境中&#xff0c;对物资进行科学规范的管理难度极大。上海岳冉基于RFID技术的建筑物资材料智能管理解决方案聚焦…

WSL系统找不到指定的文件

问题介绍 在尝试使用linux子系统时&#xff0c;发现无法打开 在尝试使用docker时无法使用 在命令行cmd或者powershell使用wls相关命令时&#xff0c;报错 相关错误提示均为&#xff1a; 系统找不到指定的文件 解决方法 试了各种方法无效。 直接到github下载最新版的wsl安装…

海量数据处理

1.海量数据处理问题 给两个文件&#xff0c;分别有100亿个query&#xff0c;只有1G内存&#xff0c;如何找到两个文件交集&#xff1f; 解决方案一&#xff1a; 可以先用布隆过滤器&#xff0c;一个文件的query放进布隆过滤器&#xff0c;另一个文件依次查找&#xff0c;在的…

英伟达GB300新宠:新型LPDDR5X SOCAMM内存

随着人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;和高性能计算&#xff08;HPC&#xff09;应用的快速发展&#xff0c;对于高效能、大容量且低延迟内存的需求日益增长。NVIDIA在其GB系列GPU中引入了不同的内存模块设计&#xff0c;以满足这些严格…

PC名词解释-笔记本的S0,S1,S2,S3,S4,S5状态

​&#x1f393;作者简介&#xff1a;程序员转项目管理领域优质创作者 &#x1f48c;个人邮箱&#xff1a;[2707492172qq.com] &#x1f310;PMP资料导航&#xff1a;PM菜鸟&#xff08;查阅PMP大纲考点&#xff09; &#x1f4a1;座右铭&#xff1a;上善若水&#xff0c;水善利…

群体智能优化算法-算术优化算法(Arithmetic Optimization Algorithm, AOA,含Matlab源代码)

摘要 算术优化算法&#xff08;Arithmetic Optimization Algorithm, AOA&#xff09;是一种新颖的群体智能优化算法&#xff0c;灵感来源于加、减、乘、除四种基本算术运算。在优化过程中&#xff0c;AOA 通过乘除操作实现全局探索&#xff0c;通过加减操作强化局部开发&#…

Centos7安装cat美化工具lolcat

Centos7安装cat美化工具lolcat Centos7安装lolcat使用ruby安装lolcat配置cat系统别名 结果验证 Centos7安装lolcat lolcat &#xff1a;一个在Linux 终端中输出彩虹特效的命令行工具 使用ruby安装lolcat # 安装ruby和zip yum install -y ruby# 查看ruby版本 ruby --version# …

vue在线录音系统

说明&#xff1a; 用vue做一款录音系统 1.点击按钮&#xff0c;开始录制音频 2.录制过程中&#xff0c;可以暂停和停止录制 有时长显示 3.点击停止录制 可以保存音频&#xff0c;保存在本地 4.找到刚刚保存的音频路径&#xff0c;可以点击播放 &#xff0c;需要显示音频总时…

参量编码LPC:原理分析与仿真实践

参量编码LPC&#xff1a;原理分析与仿真实践 在早期通信系统中&#xff0c;带宽资源有限&#xff0c;而波形编码要精确重现语音波形&#xff0c;这就需要较高的码率来传输大量数据&#xff0c;这在带宽不足的情况下就成了阻碍语音传输的大难题。随着通信技术不断进步&#xff…

猜猜我用的是哪个大模型?我的世界游戏界面简单的模拟效果

我的罗里吧嗦的&#xff0c;根据小朋友的要求&#xff0c;边听边写边输入的提示词&#xff1a; 请生成一段完整的在网页中用html5和javascript代码模拟“我的世界”中游戏场景的互动画面&#xff0c;要求提供若干人物选项可以选择&#xff0c;请自行选择需要使用哪些库或框架来…

el-radio-group 中 el-radio-button value未能绑定上数值数据

这样绑定到admin后不会随着admin的值显示 在value加上 : 后成功显示

Spring Cloud Gateway详细介绍简单案例

文章目录 1、Spring Cloud Gateway 详细介绍1.1. 统一入口&#xff08;Single Entry Point&#xff09;1.2. 请求路由&#xff08;Request Routing&#xff09;1.3. 负载均衡&#xff08;Load Balancing&#xff09;1.4. 流量控制&#xff08;Rate Limiting&#xff09;1.5. 身…