建设部网站公告注册成功网页设计与网站建设指标点
2026/5/24 4:42:59 网站建设 项目流程
建设部网站公告注册成功,网页设计与网站建设指标点,html网站简易模板,wordpress首页调用文章数大家好#xff0c;我是力哥。 最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,用到多线程去拆分数据并行处理来提高响应时间,如果有一个线程执行失败,则全部回滚#xff1b; 在spring中可以使用Transact…大家好我是力哥。最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,用到多线程去拆分数据并行处理来提高响应时间,如果有一个线程执行失败,则全部回滚在spring中可以使用Transactional注解去控制事务,使出现异常时会进行回滚,在多线程中,这个注解则不会生效,如果主线程需要先执行一些修改数据库的操作,当子线程在进行处理出现异常时,主线程修改的数据则不会回滚,导致数据错误下面用一个简单示例演示多线程事务公用的类和方法/** * 平均拆分list方法. * param source * param n * param T * return */ public static T ListListT averageAssign(ListT source,int n){ ListListT resultnewArrayListListT(); int remaidersource.size()%n; int numbersource.size()/n; int offset0;//偏移量 for(int i0;in;i){ ListT valuenull; if(remaider0){ valuesource.subList(i*numberoffset, (i1)*numberoffset1); remaider--; offset; }else{ valuesource.subList(i*numberoffset, (i1)*numberoffset); } result.add(value); } return result; }/**线程池配置 * version V1.0 */ public class ExecutorConfig { privatestaticintmaxPoolSize Runtime.getRuntime().availableProcessors(); privatevolatilestatic ExecutorService executorService; publicstatic ExecutorService getThreadPool() { if (executorService null){ synchronized (ExecutorConfig.class){ if (executorService null){ executorService newThreadPool(); } } } return executorService; } private static ExecutorService newThreadPool(){ intqueueSize500; intcorePool Math.min(5, maxPoolSize); returnnew ThreadPoolExecutor(corePool, maxPoolSize, 10000L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(queueSize),newThreadPoolExecutor.AbortPolicy()); } privateExecutorConfig(){ } }/** 获取sqlSession * version V1.0 */ Component public class SqlContext { Resource private SqlSessionTemplate sqlSessionTemplate; public SqlSession getSqlSession(){ SqlSessionFactorysqlSessionFactory sqlSessionTemplate.getSqlSessionFactory(); return sqlSessionFactory.openSession(); } }示例事务不成功操作篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】​​​/** * 测试多线程事务. * param employeeDOList */ Override Transactional(rollbackFor Exception.class) public void saveThread(ListEmployeeDO employeeDOList) { try { //先做删除操作,如果子线程出现异常,此操作不会回滚 this.getBaseMapper().delete(null); //获取线程池 ExecutorServiceservice ExecutorConfig.getThreadPool(); //拆分数据,拆分5份 ListListEmployeeDO listsaverageAssign(employeeDOList,2); //执行的线程 Thread []threadArray newThread[lists.size()]; //监控子线程执行完毕,再执行主线程,要不然会导致主线程关闭,子线程也会随着关闭 CountDownLatchcountDownLatchnewCountDownLatch(lists.size()); AtomicBooleanatomicBooleannewAtomicBoolean(false); for (inti0;ilists.size();i){ ListEmployeeDO list lists.get(i); threadArray[i] newThread(() - { try { if (!atomicBoolean.get()){ thrownew ServiceException(001,出现异常); } //批量添加,mybatisPlus中自带的batch方法 this.saveBatch(list); }finally { countDownLatch.countDown(); } }); } for (inti0; i lists.size(); i){ service.execute(threadArray[i]); } //当子线程执行完毕时,主线程再往下执行 countDownLatch.await(); System.out.println(添加完毕); }catch (Exception e){ log.info(error,e); thrownew ServiceException(002,出现异常); } }//测试用例 RunWith(SpringRunner.class) SpringBootTest(classes { ThreadTest01.class, MainApplication.class}) public class ThreadTest01 { Resource private EmployeeBO employeeBO; /** * 测试多线程事务. * throws InterruptedException */ Test public void MoreThreadTest2() throws InterruptedException { intsize10; ListEmployeeDO employeeDOList new ArrayList(size); for (inti0; isize;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 (Exception e){ e.printStackTrace(); } } }测试结果可以发现子线程组执行时,所有线程执行失败抛出异常,但是主线程中执行的删除操作,没有回滚,Transactional注解没有生效.使用sqlSession控制手动提交事务Resource SqlContext sqlContext; /** * 测试多线程事务. * param employeeDOList */ Override public void saveThread(ListEmployeeDO employeeDOList)throws SQLException { // 获取数据库连接,获取会话(内部自有事务) SqlSessionsqlSession sqlContext.getSqlSession(); Connectionconnection sqlSession.getConnection(); try { // 设置手动提交 connection.setAutoCommit(false); //获取mapper EmployeeMapperemployeeMapper sqlSession.getMapper(EmployeeMapper.class); //先做删除操作 employeeMapper.delete(null); //获取执行器 ExecutorServiceservice ExecutorConfig.getThreadPool(); ListCallableInteger callableList newArrayList(); //拆分list ListListEmployeeDO listsaverageAssign(employeeDOList, 5); for (inti0;ilists.size();i){ AtomicBooleanatomicBooleannewAtomicBoolean(true); if (ilists.size()-1){ atomicBoolean.set(false); } ListEmployeeDO list lists.get(i); //使用返回结果的callable去执行, CallableInteger callable () - { if (!atomicBoolean.get()){ thrownew ServiceException(001,出现异常); } return employeeMapper.saveBatch(list); }; callableList.add(callable); } //执行子线程 ListFutureInteger futures service.invokeAll(callableList); for (FutureInteger future:futures) { //如果有一个执行不成功,则全部回滚 if (future.get()0){ connection.rollback(); return; } } connection.commit(); System.out.println(添加完毕); }catch (Exception e){ connection.rollback(); log.info(error,e); thrownew ServiceException(002,出现异常); }finally { connection.close(); } }// sql insert idsaveBatch parameterTypeList INSERT INTO employee(employee_id,age,employee_name,birth_date,gender,id_number,creat_time,update_time,status) values foreach collectionlist itemitem indexindex separator, ( #{ item.employeeId}, #{ item.age}, #{ item.employeeName}, #{ item.birthDate}, #{ item.gender}, #{ item.idNumber}, #{ item.creatTime}, #{ item.updateTime}, #{ item.status} ) /foreach /insert数据库中一条数据篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】​​​测试结果抛出异常删除操作的数据回滚了,数据库中的数据依旧存在,说明事务成功了.成功操作示例Resource SqlContext sqlContext; /** * 测试多线程事务. * param employeeDOList */ Override public void saveThread(ListEmployeeDO employeeDOList)throws SQLException { // 获取数据库连接,获取会话(内部自有事务) SqlSessionsqlSession sqlContext.getSqlSession(); Connectionconnection sqlSession.getConnection(); try { // 设置手动提交 connection.setAutoCommit(false); EmployeeMapperemployeeMapper sqlSession.getMapper(EmployeeMapper.class); //先做删除操作 employeeMapper.delete(null); ExecutorServiceservice ExecutorConfig.getThreadPool(); ListCallableInteger callableList newArrayList(); ListListEmployeeDO listsaverageAssign(employeeDOList, 5); for (inti0;ilists.size();i){ ListEmployeeDO list lists.get(i); CallableInteger callable () - employeeMapper.saveBatch(list); callableList.add(callable); } //执行子线程 ListFutureInteger futures service.invokeAll(callableList); for (FutureInteger future:futures) { if (future.get()0){ connection.rollback(); return; } } connection.commit(); System.out.println(添加完毕); }catch (Exception e){ connection.rollback(); log.info(error,e); thrownew ServiceException(002,出现异常); // throw new ServiceException(ExceptionCodeEnum.EMPLOYEE_SAVE_OR_UPDATE_ERROR); } }数据库中数据删除的删除了,添加的添加成功了,测试成功.

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询