关系经济人类预测化学自然
投稿投诉
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产

支付宝一面多线程事务怎么回滚?

2月10日 呛人心投稿
  背景介绍
  1。最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,用到多线程去拆分数据并行处理来提高响应时间,如果有一个线程执行失败,则全部回滚。
  2。在spring中可以使用Transactional注解去控制事务,使出现异常时会进行回滚,在多线程中,这个注解则不会生效,如果主线程需要先执行一些修改数据库的操作,当子线程在进行处理出现异常时,主线程修改的数据则不会回滚,导致数据错误。
  3。下面用一个简单示例演示多线程事务。公用的类和方法平均拆分list方法。paramsourceparamnparamTreturnpublicstaticTListListTaverageAssign(ListTsource,intn){ListListTresultnewArrayListListT();intremaidersource。size()n;intnumbersource。size()n;intoffset0;偏移量for(inti0;i){ListTif(remaider0){valuesource。subList(inumberoffset,(i1)numberoffset1);}else{valuesource。subList(inumberoffset,(i1)numberoffset);}result。add(value);}}线程池配置versionV1。0publicclassExecutorConfig{privatestaticintmaxPoolSizeRuntime。getRuntime()。availableProcessors();privatevolatilestaticExecutorServiceexecutorSpublicstaticExecutorServicegetThreadPool(){if(executorServicenull){synchronized(ExecutorConfig。class){if(executorServicenull){executorServicenewThreadPool();}}}returnexecutorS}privatestaticExecutorServicenewThreadPool(){intqueueSize500;intcorePoolMath。min(5,maxPoolSize);returnnewThreadPoolExecutor(corePool,maxPoolSize,10000L,TimeUnit。MILLISECONDS,newLinkedBlockingQueue(queueSize),newThreadPoolExecutor。AbortPolicy());}privateExecutorConfig(){}}获取sqlSessionauthor86182versionV1。0ComponentpublicclassSqlContext{ResourceprivateSqlSessionTemplatesqlSessionTpublicSqlSessiongetSqlSession(){SqlSessionFactorysqlSessionFactorysqlSessionTemplate。getSqlSessionFactory();returnsqlSessionFactory。openSession();}}示例事务不成功操作测试多线程事务。paramemployeeDOListOverrideTransactionalpublicvoidsaveThread(ListEmployeeDOemployeeDOList){try{先做删除操作,如果子线程出现异常,此操作不会回滚this。getBaseMapper()。delete(null);获取线程池ExecutorServiceserviceExecutorConfig。getThreadPool();拆分数据,拆分5份ListListEmployeeDOlistsaverageAssign(employeeDOList,5);执行的线程Thread〔〕threadArraynewThread〔lists。size()〕;监控子线程执行完毕,再执行主线程,要不然会导致主线程关闭,子线程也会随着关闭CountDownLatchcountDownLatchnewCountDownLatch(lists。size());AtomicBooleanatomicBooleannewAtomicBoolean(true);for(inti0;ilists。size();i){if(ilists。size()1){atomicBoolean。set(false);}ListEmployeeDOlistlists。get(i);threadArray〔i〕newThread((){try{最后一个线程抛出异常if(!atomicBoolean。get()){thrownewServiceException(001,出现异常);}批量添加,mybatisPlus中自带的batch方法this。saveBatch(list);}finally{countDownLatch。countDown();}});}for(inti0;ilists。size();i){service。execute(threadArray〔i〕);}当子线程执行完毕时,主线程再往下执行countDownLatch。await();System。out。println(添加完毕);}catch(Exceptione){log。info(error,e);thrownewServiceException(002,出现异常);}finally{connection。close();}}
  数据库中存在一条数据:
  测试用例RunWith(SpringRunner。class)SpringBootTest(classes{ThreadTest01。class,MainApplication。class})publicclassThreadTest01{ResourceprivateEmployeeBOemployeeBO;测试多线程事务。throwsInterruptedExceptionTestpublicvoidMoreThreadTest2()throwsInterruptedException{intsize10;ListEmployeeDOemployeeDOListnewArrayList(size);for(inti0;i){EmployeeDOemployeeDOnewEmployeeDO();employeeDO。setEmployeeName(loli);employeeDO。setAge(18);employeeDO。setGender(1);employeeDO。setIdNumber(iXX);employeeDO。setCreatTime(Calendar。getInstance()。getTime());employeeDOList。add(employeeDO);}try{employeeBO。saveThread(employeeDOList);System。out。println(添加成功);}catch(Exceptione){e。printStackTrace();}}}
  测试结果:
  可以发现子线程组执行时,有一个线程执行失败,其他线程也会抛出异常,但是主线程中执行的删除操作,没有回滚,Transactional注解没有生效。使用sqlSession控制手动提交事务ResourceSqlContextsqlC测试多线程事务。paramemployeeDOListOverridepublicvoidsaveThread(ListEmployeeDOemployeeDOList)throwsSQLException{获取数据库连接,获取会话(内部自有事务)SqlSessionsqlSessionsqlContext。getSqlSession();ConnectionconnectionsqlSession。getConnection();try{设置手动提交connection。setAutoCommit(false);获取mapperEmployeeMapperemployeeMappersqlSession。getMapper(EmployeeMapper。class);先做删除操作employeeMapper。delete(null);获取执行器ExecutorServiceserviceExecutorConfig。getThreadPool();ListCallableIntegercallableListnewArrayList();拆分listListListEmployeeDOlistsaverageAssign(employeeDOList,5);AtomicBooleanatomicBooleannewAtomicBoolean(true);for(inti0;ilists。size();i){if(ilists。size()1){atomicBoolean。set(false);}ListEmployeeDOlistlists。get(i);使用返回结果的callable去执行,CallableIntegercallable(){让最后一个线程抛出异常if(!atomicBoolean。get()){thrownewServiceException(001,出现异常);}returnemployeeMapper。saveBatch(list);};callableList。add(callable);}执行子线程ListFutureIntegerfuturesservice。invokeAll(callableList);for(FutureIntegerfuture:futures){如果有一个执行不成功,则全部回滚if(future。get()0){connection。rollback();}}connection。commit();System。out。println(添加完毕);}catch(Exceptione){connection。rollback();log。info(error,e);thrownewServiceException(002,出现异常);}finally{connection。close();}}sqlinsertidsaveBatchparameterTypeListINSERTINTOemployee(employeeid,age,employeename,birthdate,gender,idnumber,creattime,updatetime,status)valuesforeachcollectionlistitemitemindexindexseparator,({item。employeeId},{item。age},{item。employeeName},{item。birthDate},{item。gender},{item。idNumber},{item。creatTime},{item。updateTime},{item。status})foreachinsert
  数据库中一条数据:
  测试结果,抛出异常:
  删除操作的数据回滚了,数据库中的数据依旧存在,说明事务成功了。
  成功操作示例:ResourceSqlContextsqlC测试多线程事务。paramemployeeDOListOverridepublicvoidsaveThread(ListEmployeeDOemployeeDOList)throwsSQLException{获取数据库连接,获取会话(内部自有事务)SqlSessionsqlSessionsqlContext。getSqlSession();ConnectionconnectionsqlSession。getConnection();try{设置手动提交connection。setAutoCommit(false);EmployeeMapperemployeeMappersqlSession。getMapper(EmployeeMapper。class);先做删除操作employeeMapper。delete(null);ExecutorServiceserviceExecutorConfig。getThreadPool();ListCallableIntegercallableListnewArrayList();ListListEmployeeDOlistsaverageAssign(employeeDOList,5);for(inti0;ilists。size();i){ListEmployeeDOlistlists。get(i);CallableIntegercallable()employeeMapper。saveBatch(list);callableList。add(callable);}执行子线程ListFutureIntegerfuturesservice。invokeAll(callableList);for(FutureIntegerfuture:futures){if(future。get()0){connection。rollback();}}connection。commit();System。out。println(添加完毕);}catch(Exceptione){connection。rollback();log。info(error,e);thrownewServiceException(002,出现异常);thrownewServiceException(ExceptionCodeEnum。EMPLOYEESAVEORUPDATEERROR);}}
  测试结果:
  数据库中数据:
  删除的删除了,添加的添加成功了,测试成功。
  来源:blog。csdn。netweixin43225491articledetails117705686
投诉 评论 转载

保卫萝卜4阿波尼克号第23关通关攻略保卫萝卜4阿波尼克号第23关通关攻略是什么?保卫萝卜4阿波尼克号第23关通关流程是什么?保卫萝卜4阿波尼克号第23关操作顺序是什么?保卫萝卜4是一款最新上线的国民塔防闯关游戏续……梦幻西游期对新版钓鱼赚钱的认知两小时各位早上好啊!(可能你们看到这个文案的时候应该是周一的下午了)前言:本文讲述了,五开钓鱼的最低收入问题,以及特殊事件带来的巨额收入,文末有我对钓鱼系统的理解,以及给大家提……钟馗复活一、破台咚咚咚所有灯火俱已熄灭,前后台的门也上了锁,黑暗中,只有堂鼓声沉沉地回荡着。猛地,四条惨白的细长影子蹿上台来,僵直地左蹦右跳着。旋即,又一道壮实的身影出现,……情绪文案心软穷半生,多情空余恨3月财经新势力一个从不回头的人,未必是因为勇敢,也许是怕被识破脸上的泪痕。一个时刻微笑的人,未必是因为快乐,可能是怕被看穿心底的叹息。一位老先生说过……孔子真的像我们印象中的那么柔弱吗大家都知道,孔子是中国古代的大思想家,大教育家,是儒家学派的创始人。他兴办私学,突破官府垄断,扩大教育对象的范围,是当时社会上的最博学者之一,其儒家思想对中国和世界都有深远的影……9月6日正式发布,华为新款二合一笔记本MateBookEGo随着混合办公模式的逐渐流行,办公室,家里、咖啡厅、图书馆等地点都成为了移动办公人群常见的办公场所。在用户移动办公场景和需求的转变下,移动办公设备也在悄悄发生变化,消费者对移动办……引起肥胖的疾病有哪些(1)单纯性肥胖:一是营养过剩,进食大量油腻及甜食,活动过少;二是相对性的营养不良,主要是偏食、异食等造成的维生素及蛋白质不足。活动过少和饭后即睡是形成儿童肥胖的一个不良习惯。……丝袜有什么用处丝袜是一种服饰用品,穿着者多为女性。多数是连身的,有皮肤色、黑色、白色等颜色,是女人的第二层皮肤,也是每个女性必备的单品。据说,十六世纪时已经出现丝袜的雏形,那么,作为一种装饰……如何做好冰箱基础体验,TCL格物系列冰箱保鲜效果一定要到位现代冰箱最重要的基础体验是什么,容量、运行噪音,还是能耗?其实都不是,随着生活品质的逐渐增加,我们对于食材的品质要求也在不断提升,因此保鲜技术就慢慢变成了现代冰箱最重要的基础体……支付宝一面多线程事务怎么回滚?背景介绍1。最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,用到多线程去拆分数据并行处理来提高响应时间,……新菲总统下令,撤回中菲49亿美元铁路项目,重审杜特尔特决议案菲律宾前总统杜特尔特在任期间与中国签署了多项合作协议,有效地促进了菲律宾的发展。可是菲律宾新总统上任后,却开始在一些问题上反悔了,菲总统小马科斯突然下达命令,撕毁了此前与中国达……员工为马斯克买玻璃被开除,超导量子芯片成果发布,谷歌冻结招聘日报君发自凹非寺量子位公众号QbitAI大家好,今天是周五,工作日的最后一天啦今天科技圈都有哪些好玩的事呢?一起来跟日报君看看吧。今日大新闻马斯克以权谋……
人参西洋参党参太子参功效大不同,进补该用哪种?跟着安琪一起开始酵母细胞的太空之旅额头脸上小颗粒!十几岁皮肤护理!变美游戏行业如何自律?广州互联网企业联合推出未成年人网络保护管理网络货运群雄并起,超好运仅用两年凭实力强势突围卫冕冠军不敌辽篮输掉半决赛首战,内线劣势阵容厚度成为两大短板精不足则多食,爱不足则多情,信不足则多言NBA哈登浓眉哥落选全明星阵容VCPE市场观察超实用洗面奶测评去除肌肤老废角质与污垢,残留,令肌肤清爽净透神奇九寨沟的这18个奇妙旅游景点,你知道几个呢?恭喜内马尔,逼宫大获成功!姆总改变态度,可转型中场为新援让位
马虎小学作文香菜的热量高吗香菜减肥期间可以吃吗写给国税局的感谢信范文和玻璃一样透明的是什么材质象玻璃一样透明的是什么材质商号与商标的区别有哪些工作计划精华〔9篇〕雍正宝石红釉摇铃尊鉴赏童装强制性标准的好处有哪些我身边的活雷锋员工因材适用才能人尽其才别管会不会,先忙起来的5个优势,没有领导不。。。心系那座山

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找菏泽德阳山西湖州宝鸡上海茂名内江三亚信阳长春北海西安安徽黄石烟台沧州湛江肇庆鹤壁六安韶关成都钦州