使用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.pswp.cn/pingmian/73929.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73929.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73929.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Cannot find a valid baseurl for repo: centos-sclo-sclo/x86_64

? rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-latest-5.0.el7.noarch.rpmyum clean allyum macache fast? 編輯配置文件 /etc/yum.repos.d/zabbix.repo and enable zabbix-frontend repository. [zabbix-frontend]...enabled1... 下載相關…

AI基礎02-圖片數據采集

上篇文章我們學習了文本的數據采集&#xff0c;今天主要了解一下圖片數據采集的方法。圖片采集方法通常有網頁采集和實時采集&#xff08;傳感器采集&#xff09;兩種。我們學習一下如何利用python 工具和筆記本計算機攝像頭進行圖片數據的實時采集。 1&#xff09;cv2庫簡介 …

【CSS】相對位置小練習

要求&#xff1a; 成果&#xff1a; 代碼&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>相對位置小練習</title><link rel"stylesheet" href"./css/style.css…

外設的中斷控制

如ADC、SPI、I2C、TIM等使用STM32 HAL庫時的中斷函數調用方式和UART非常類似&#xff0c;都有底層直接使能中斷和上層庫函數管理兩種方式。下面詳細說明幾種典型外設&#xff1a; 一、ADC外設 &#xff08;1&#xff09;直接使能中斷&#xff08;底層控制&#xff09;&#xf…

網絡傳輸優化之多路復用與解復用

一、基本概念 多路復用 發送端將來自多個應用或進程的數據流合并到同一物理信道中傳輸的過程。核心目的是提高信道利用率&#xff0c;減少資源浪費。例如&#xff0c;多個網絡應用&#xff08;如瀏覽器、郵件客戶端&#xff09;通過不同端口將數據封裝為報文段&#xff0c;共享…

【軟考-架構】10.1、軟件工程概述-CMM-軟件過程模型-逆向工程

?資料&文章更新? GitHub地址&#xff1a;https://github.com/tyronczt/system_architect 文章目錄 軟件工程基礎知識軟件工程概述能力成熟度模型能力成熟度模型CMM能力成熟度模型集成CMMI &#x1f4af;考試真題第一題第二題 軟件過程模型瀑布模型&#xff08;SDLC&#…

python將整個txt文件寫入excel的一個單元格?

要將整個txt文件寫入Excel的一個單元格&#xff0c;可以使用Python的openpyxl庫來實現。以下是一個簡單的示例代碼&#xff1a; from openpyxl import Workbook# 讀取txt文件內容 with open(file.txt, r) as file:txt_content file.read()# 創建一個新的Excel工作簿 wb Work…

車載以太網網絡測試 -25【SOME/IP-報文格式-1】

1 摘要 本專題接著上一專題對SOME/IP進行介紹&#xff0c;主要對SOME/IP報文格式以及定義的字段進行詳細介紹&#xff0c;有助于在實際項目過程中對SOME/IP報文的理解。 上文回顧&#xff1a; 車載以太網網絡測試 -24【SOME/IP概述】 2 SOME/IP-報文格式 通過上個專題介紹&a…

【區塊鏈安全 | 第五篇】DeFi概念詳解

文章目錄 DeFi1. DeFi 生態概覽2. 去中心化交易所&#xff08;DEX&#xff09;2.1 AMM&#xff08;自動做市商&#xff09;模型2.2 訂單簿模式&#xff08;現貨交易&#xff09; 3. 借貸協議3.1 Aave3.2 使用閃電貸&#xff08;Flash Loan&#xff09; 4. 穩定幣&#xff08;St…

問題:md文檔轉換word,html,圖片,excel,csv

文章目錄 問題&#xff1a;md文檔轉換word&#xff0c;html&#xff0c;圖片&#xff0c;excel&#xff0c;csv&#xff0c;ppt**主要職責****技能要求****發展方向****學習建議****薪資水平** 方案一&#xff1a;AI Markdown內容轉換工具打開網站md文檔轉換wordmd文檔轉換pdfm…

代碼隨想錄刷題day53|(二叉樹篇)106.從中序與后序遍歷序列構造二叉樹(▲

目錄 一、二叉樹理論知識 二、構造二叉樹思路 2.1 構造二叉樹流程&#xff08;給定中序后序 2.2 整體步驟 2.3 遞歸思路 2.4 給定前序和后序 三、相關算法題目 四、易錯點 一、二叉樹理論知識 詳見&#xff1a;代碼隨想錄刷題day34|&#xff08;二叉樹篇&#xff09;二…

前端知識點---用正則表達式判斷郵箱(javascript)

// 全面的正則&#xff08;兼容大多數情況&#xff09; const emailRegex /^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$/;// 或直接使用瀏覽器內置驗證 <input type"email" required>/&#xff1a;正則表達式的起始和結束標志。 ^&#xff1a;匹配字符串的…

PyQt6實例_批量下載pdf工具_界面開發

目錄 前置&#xff1a; 代碼&#xff1a; 視頻&#xff1a; 前置&#xff1a; 1 本系列將以 “PyQt6實例_批量下載pdf工具”開頭&#xff0c;放在 【PyQt6實例】 專欄 2 本系列涉及到的PyQt6知識點&#xff1a; 線程池&#xff1a;QThreadPool,QRunnable&#xff1b; 信號…

在word中使用zotero添加參考文獻并附帶超鏈接

一、引言 在寫大論文時&#xff0c;為了避免文中引用與文末參考文獻頻繁對照、修改文中引用順序/引用文獻時手動維護參考文獻耗易出錯&#xff0c;擬在 word 中使用 zotero 插入參考文獻&#xff0c;并為每個參考文獻附加超鏈接&#xff0c;實現交互式閱讀。 版本&#xff1a…

Selenium文件上傳

在 Web 自動化測試中,文件上傳是一項常見的任務。不同的網站和前端技術可能導致上傳方式有所不同,因此需要采用不同的方法進行處理。 方法 1:使用 send_keys() 直接上傳(最常用) 適用場景: 頁面中 有標準的 <input type="file"> 標簽。 不需要彈出 Wind…

線程概念與控制(中)

線程概念與控制&#xff08;上&#xff09;https://blog.csdn.net/Small_entreprene/article/details/146464905?sharetypeblogdetail&sharerId146464905&sharereferPC&sharesourceSmall_entreprene&sharefrommp_from_link我們經過上一篇的學習&#xff0c;接…

【Unity】 鼠標拖動物體移動速度跟不上鼠標,會掉落

錯誤示范&#xff1a; 一開始把移動的代碼寫到update里去了&#xff0c;發現物體老是掉(總之移動非常不流暢&#xff0c;體驗感很差&#xff09; void Update(){Ray ray Camera.main.ScreenPointToRay(Input.mousePosition);if (Physics.Raycast(ray, out RaycastHit hit, M…

MATLAB 控制系統設計與仿真 - 30

用極點配置設計伺服系統 方法2-反饋修正 如果我們想只用前饋校正輸入&#xff0c;從而達到伺服控制的效果&#xff0c;我們需要很精確的知道系統的參數模型&#xff0c;否則系統輸出仍然具有較大的靜態誤差。 但是如果我們在誤差比較器和系統的前饋通道之間插入一個積分器&a…

VMware Windows Tools 存在認證繞過漏洞(CVE-2025-22230)

漏洞概述 博通公司&#xff08;Broadcom&#xff09;近日修復了 VMware Windows Tools 中存在的一個高危認證繞過漏洞&#xff0c;該漏洞編號為 CVE-2025-22230&#xff08;CVSS 評分為 9.8&#xff09;。VMware Windows Tools 是一套實用程序套件&#xff0c;可提升運行在 VM…

羅杰斯特回歸

定義 邏輯回歸其實就是原來的線性回歸加了激活函數&#xff0c;這個函數其實就是sigmoid函數&#xff0c;把一個回歸的連續數值壓縮到了0到1的空間&#xff0c;其實只要有函數能夠滿足把數值壓縮到0,1之間就可以&#xff08;因為0到1之間的數值就是概率值&#xff09; 對于分類…