国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

支付寶:多線程事務怎么回滾?

jf_ro2CN3Fa ? 來源:CSDN ? 2023-01-09 11:42 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群


背景介紹

1,最近有一個大數據量插入的操作入庫的業(yè)務場景,需要先做一些其他修改操作,然后在執(zhí)行插入操作,由于插入數據可能會很多,用到多線程去拆分數據并行處理來提高響應時間,如果有一個線程執(zhí)行失敗,則全部回滾。

2,在spring中可以使用@Transactional注解去控制事務,使出現異常時會進行回滾,在多線程中,這個注解則不會生效,如果主線程需要先執(zhí)行一些修改數據庫的操作,當子線程在進行處理出現異常時,主線程修改的數據則不會回滾,導致數據錯誤。

3,下面用一個簡單示例演示多線程事務。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

公用的類和方法

/**
*平均拆分list方法.
*@paramsource
*@paramn
*@param
*@return
*/
publicstaticList>averageAssign(Listsource,intn){
List>result=newArrayList>();
intremaider=source.size()%n;
intnumber=source.size()/n;
intoffset=0;//偏移量
for(inti=0;ivalue=null;
if(remaider>0){
value=source.subList(i*number+offset,(i+1)*number+offset+1);
remaider--;
offset++;
}else{
value=source.subList(i*number+offset,(i+1)*number+offset);
}
result.add(value);
}
returnresult;
}
/**線程池配置
*@versionV1.0
*/
publicclassExecutorConfig{
privatestaticintmaxPoolSize=Runtime.getRuntime().availableProcessors();
privatevolatilestaticExecutorServiceexecutorService;
publicstaticExecutorServicegetThreadPool(){
if(executorService==null){
synchronized(ExecutorConfig.class){
if(executorService==null){
executorService=newThreadPool();
}
}
}
returnexecutorService;
}

privatestaticExecutorServicenewThreadPool(){
intqueueSize=500;
intcorePool=Math.min(5,maxPoolSize);
returnnewThreadPoolExecutor(corePool,maxPoolSize,10000L,TimeUnit.MILLISECONDS,
newLinkedBlockingQueue<>(queueSize),newThreadPoolExecutor.AbortPolicy());
}
privateExecutorConfig(){}
}
/**獲取sqlSession
*@author86182
*@versionV1.0
*/
@Component
publicclassSqlContext{
@Resource
privateSqlSessionTemplatesqlSessionTemplate;

publicSqlSessiongetSqlSession(){
SqlSessionFactorysqlSessionFactory=sqlSessionTemplate.getSqlSessionFactory();
returnsqlSessionFactory.openSession();
}
}

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

示例事務不成功操作

/**
*測試多線程事務.
*@paramemployeeDOList
*/
@Override
@Transactional
publicvoidsaveThread(ListemployeeDOList){
try{
//先做刪除操作,如果子線程出現異常,此操作不會回滾
this.getBaseMapper().delete(null);
//獲取線程池
ExecutorServiceservice=ExecutorConfig.getThreadPool();
//拆分數據,拆分5份
List>lists=averageAssign(employeeDOList,5);
//執(zhí)行的線程
Thread[]threadArray=newThread[lists.size()];
//監(jiān)控子線程執(zhí)行完畢,再執(zhí)行主線程,要不然會導致主線程關閉,子線程也會隨著關閉
CountDownLatchcountDownLatch=newCountDownLatch(lists.size());
AtomicBooleanatomicBoolean=newAtomicBoolean(true);
for(inti=0;iif(i==lists.size()-1){
atomicBoolean.set(false);
}
Listlist=lists.get(i);
threadArray[i]=newThread(()->{
try{
//最后一個線程拋出異常
if(!atomicBoolean.get()){
thrownewServiceException("001","出現異常");
}
//批量添加,mybatisPlus中自帶的batch方法
this.saveBatch(list);
}finally{
countDownLatch.countDown();
}

});
}
for(inti=0;i//當子線程執(zhí)行完畢時,主線程再往下執(zhí)行
countDownLatch.await();
System.out.println("添加完畢");
}catch(Exceptione){
log.info("error",e);
thrownewServiceException("002","出現異常");
}finally{
connection.close();
}
}

數據庫中存在一條數據:

07f6f516-8fc2-11ed-bfe3-dac502259ad0.png
//測試用例
@RunWith(SpringRunner.class)
@SpringBootTest(classes={ThreadTest01.class,MainApplication.class})
publicclassThreadTest01{

@Resource
privateEmployeeBOemployeeBO;

/**
*測試多線程事務.
*@throwsInterruptedException
*/
@Test
publicvoidMoreThreadTest2()throwsInterruptedException{
intsize=10;
ListemployeeDOList=newArrayList<>(size);
for(inti=0;inewEmployeeDO();
employeeDO.setEmployeeName("lol"+i);
employeeDO.setAge(18);
employeeDO.setGender(1);
employeeDO.setIdNumber(i+"XX");
employeeDO.setCreatTime(Calendar.getInstance().getTime());
employeeDOList.add(employeeDO);
}
try{
employeeBO.saveThread(employeeDOList);
System.out.println("添加成功");
}catch(Exceptione){
e.printStackTrace();
}
}
}

測試結果:

08028656-8fc2-11ed-bfe3-dac502259ad0.png08120248-8fc2-11ed-bfe3-dac502259ad0.png

可以發(fā)現子線程組執(zhí)行時,有一個線程執(zhí)行失敗,其他線程也會拋出異常,但是主線程中執(zhí)行的刪除操作,沒有回滾,@Transactional注解沒有生效。

使用sqlSession控制手動提交事務

@Resource
SqlContextsqlContext;
/**
*測試多線程事務.
*@paramemployeeDOList
*/
@Override
publicvoidsaveThread(ListemployeeDOList)throwsSQLException{
//獲取數據庫連接,獲取會話(內部自有事務)
SqlSessionsqlSession=sqlContext.getSqlSession();
Connectionconnection=sqlSession.getConnection();
try{
//設置手動提交
connection.setAutoCommit(false);
//獲取mapper
EmployeeMapperemployeeMapper=sqlSession.getMapper(EmployeeMapper.class);
//先做刪除操作
employeeMapper.delete(null);
//獲取執(zhí)行器
ExecutorServiceservice=ExecutorConfig.getThreadPool();
List>callableList=newArrayList<>();
//拆分list
List>lists=averageAssign(employeeDOList,5);
AtomicBooleanatomicBoolean=newAtomicBoolean(true);
for(inti=0;iif(i==lists.size()-1){
atomicBoolean.set(false);
}
Listlist=lists.get(i);
//使用返回結果的callable去執(zhí)行,
Callablecallable=()->{
//讓最后一個線程拋出異常
if(!atomicBoolean.get()){
thrownewServiceException("001","出現異常");
}
returnemployeeMapper.saveBatch(list);
};
callableList.add(callable);
}
//執(zhí)行子線程
List>futures=service.invokeAll(callableList);
for(Futurefuture:futures){
//如果有一個執(zhí)行不成功,則全部回滾
if(future.get()<=0){
connection.rollback();
return;
}
}
connection.commit();
System.out.println("添加完畢");
}catch(Exceptione){
connection.rollback();
log.info("error",e);
thrownewServiceException("002","出現異常");
}finally{
connection.close();
}
}
//sql
"saveBatch"parameterType="List">
INSERTINTO
employee(employee_id,age,employee_name,birth_date,gender,id_number,creat_time,update_time,status)
values
="list"item="item"index="index"separator=",">
(
#{item.employeeId},
#{item.age},
#{item.employeeName},
#{item.birthDate},
#{item.gender},
#{item.idNumber},
#{item.creatTime},
#{item.updateTime},
#{item.status}
)


數據庫中一條數據:

081f036c-8fc2-11ed-bfe3-dac502259ad0.png

測試結果:拋出異常,

0836bc00-8fc2-11ed-bfe3-dac502259ad0.png

刪除操作的數據回滾了,數據庫中的數據依舊存在,說明事務成功了。

0847e7d2-8fc2-11ed-bfe3-dac502259ad0.png

成功操作示例:

@Resource
SqlContextsqlContext;
/**
*測試多線程事務.
*@paramemployeeDOList
*/
@Override
publicvoidsaveThread(ListemployeeDOList)throwsSQLException{
//獲取數據庫連接,獲取會話(內部自有事務)
SqlSessionsqlSession=sqlContext.getSqlSession();
Connectionconnection=sqlSession.getConnection();
try{
//設置手動提交
connection.setAutoCommit(false);
EmployeeMapperemployeeMapper=sqlSession.getMapper(EmployeeMapper.class);
//先做刪除操作
employeeMapper.delete(null);
ExecutorServiceservice=ExecutorConfig.getThreadPool();
List>callableList=newArrayList<>();
List>lists=averageAssign(employeeDOList,5);
for(inti=0;ilist=lists.get(i);
Callablecallable=()->employeeMapper.saveBatch(list);
callableList.add(callable);
}
//執(zhí)行子線程
List>futures=service.invokeAll(callableList);
for(Futurefuture:futures){
if(future.get()<=0){
connection.rollback();
return;
}
}
connection.commit();
System.out.println("添加完畢");
}catch(Exceptione){
connection.rollback();
log.info("error",e);
thrownewServiceException("002","出現異常");
//thrownewServiceException(ExceptionCodeEnum.EMPLOYEE_SAVE_OR_UPDATE_ERROR);
}
}

測試結果:

08585db0-8fc2-11ed-bfe3-dac502259ad0.png

數據庫中數據:

刪除的刪除了,添加的添加成功了,測試成功。

0869dc84-8fc2-11ed-bfe3-dac502259ad0.png

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 多線程
    +關注

    關注

    0

    文章

    279

    瀏覽量

    21027
  • spring
    +關注

    關注

    0

    文章

    341

    瀏覽量

    15935

原文標題:支付寶:多線程事務怎么回滾?說用 @Transactional 可以回去等通知了!

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    【瑞薩RA × Zephyr評測】多線程和看門狗

    本文章旨在評估使用 Zephyr RTOS 在 Renesas FPB-RA6E2 開發(fā)板上實現多線程調度與硬件看門狗功能的應用。評估內容包括任務調度、看門狗初始化流程、主程序邏輯的詳細解析,以及實驗現象與數據分析。
    的頭像 發(fā)表于 01-10 10:23 ?2465次閱讀
    【瑞薩RA × Zephyr評測】<b class='flag-5'>多線程</b>和看門狗

    支付寶FluidMarkdown鴻蒙版正式開源

    近日,支付寶正式開源面向鴻蒙平臺的 FluidMarkdown ——一款專為智能化業(yè)務場景打造的移動端 Markdown 渲染庫。作為首個適配 HarmonyOS 平臺的流式 Markdown 引擎
    的頭像 發(fā)表于 12-26 13:42 ?616次閱讀

    華為與中移互聯(lián)網、支付寶簽署戰(zhàn)略合作協(xié)議

    今日,為推進AI新通信生態(tài)繁榮,中移互聯(lián)網有限公司(以下簡稱“中移互聯(lián)網”)、支付寶(杭州)數字服務技術有限公司(以下簡稱“支付寶”)及華為技術有限公司(以下簡稱“華為”)正式簽署合作協(xié)議,共同開啟
    的頭像 發(fā)表于 12-17 16:41 ?647次閱讀

    多線程的系統(tǒng)

    多線程系統(tǒng)的事件響應也是在中斷中完成的,但事件的處理是在線程中完成的。在多線程系統(tǒng)中,線程跟中斷一樣,也具有優(yōu)先級,優(yōu)先級高的線程會被優(yōu)先執(zhí)
    發(fā)表于 12-08 07:55

    Linux多線程對比單線程的優(yōu)勢

    :「資源利用率」:通過多線程,可以更有效地利用CPU資源,特別是多核CPU。「并行處理」:線程允許同時執(zhí)行多個任務,提高程序的執(zhí)行效率。「簡化設計」:使用線程可以簡化程序設計,因為線程
    發(fā)表于 12-01 06:11

    支付寶“碰一下”的革新背后:國民技術MCU的隱形力量

    近日,全球頂尖金融科技盛會Money20/20公布首屆創(chuàng)新大獎TheMoneyAwards結果,“支付寶碰一下”從眾多參賽企業(yè)中脫穎而出,憑借創(chuàng)新的解決方案和極致的用戶體驗摘得“支付”類別大獎,成為
    的頭像 發(fā)表于 11-21 19:15 ?1337次閱讀
    <b class='flag-5'>支付寶</b>“碰一下”的革新背后:國民技術MCU的隱形力量

    基于IAP功能實現遠程升級,如何設計Flash雙Bank熱切換的機制?

    基于IAP功能實現遠程升級時,如何設計Flash雙Bank熱切換的機制?
    發(fā)表于 11-21 07:26

    廣汽能源與支付寶深化戰(zhàn)略合作

    2025年11月14日,廣汽能源科技有限公司(以下簡稱“廣汽能源”)與支付寶(杭州)數字服務技術有限公司(以下簡稱“支付寶”)在廣汽集團總部舉行深化合作簽約儀式。廣汽集團副總經理鄭衡、螞蟻集團支付寶
    的頭像 發(fā)表于 11-18 10:19 ?639次閱讀

    國民技術MCU芯片護航支付寶碰一下設備創(chuàng)新

    近日,全球頂尖金融科技盛會Money20/20公布首屆創(chuàng)新大獎The Money Awards結果,“支付寶碰一下”從眾多參賽企業(yè)中脫穎而出,憑借創(chuàng)新的解決方案和極致的用戶體驗摘得“支付”類別大獎,成為該類別中唯一的中國企業(yè)。
    的頭像 發(fā)表于 11-06 10:15 ?1129次閱讀

    rt-thread studio 如何進行多線程編譯?

    ,使用的是5800h+32g內存+sn550 ssd,開啟16線程編譯時cpu的占用率也只能到30%,編譯完整個工程需要3分鐘 感覺多線程編譯設置沒有生效,有辦法提高編譯速度嗎 rtthread studio版本是 2.2.9
    發(fā)表于 10-11 09:16

    淘寶/天貓:使用支付寶API實現多場景支付,覆蓋用戶偏好

    ? ?在淘寶和天貓等電商平臺上,支付體驗直接影響用戶滿意度和轉化率。支付寶作為核心支付工具,其開放API(Application Programming Interface)允許開發(fā)者靈活集成多場景
    的頭像 發(fā)表于 09-25 09:59 ?777次閱讀
    淘寶/天貓:使用<b class='flag-5'>支付寶</b>API實現多場景<b class='flag-5'>支付</b>,覆蓋用戶偏好

    奧比中光助力支付寶碰一下落地電梯場景

    近日,支付寶與分眾傳媒宣布聯(lián)合推出“碰一下?lián)尲t包”服務。作為創(chuàng)新交互方式,“支付寶碰一下”首次被引入至電梯場景,并已在全國20余個城市的電梯鋪設。奧比中光作為“支付寶碰一下”業(yè)務的核心供應商,為這一創(chuàng)新交互方式首次大規(guī)模落地電梯
    的頭像 發(fā)表于 08-12 11:32 ?1223次閱讀

    多線程的安全注意事項

    多線程安全是指多個線程同時訪問或修改共享資源時,能夠保證程序的正確性和可靠性。 開發(fā)者選擇TaskPool或Worker進行多線程開發(fā)時,在TaskPool和Worker的工作線程中導
    發(fā)表于 06-20 07:49

    復旦微電子與支付寶推出“碰一下”射頻芯片

    近日,由支付寶主辦的「碰一下·奇妙小鎮(zhèn)」生態(tài)大會在杭州·運河文化發(fā)布中心隆重舉辦。大會場景覆蓋餐飲、商圈MALL、出行、政務、醫(yī)療、物流等多個領域,以服務商、供應鏈伙伴和終端廠商為代表的生態(tài)伙伴共同參與,超300家頭部合作伙伴創(chuàng)始人/CEO參加大會。
    的頭像 發(fā)表于 04-28 09:46 ?1387次閱讀

    請問如何在Python中實現多線程與多進程的協(xié)作?

    大家好!我最近在開發(fā)一個Python項目時,需要同時處理多個任務,且每個任務需要不同的計算資源。我想通過多線程和多進程的組合來實現并發(fā),但遇到了一些問題。 具體來說,我有兩個任務,一個是I/O密集型
    發(fā)表于 03-11 06:57