当前位置: 首页 > news >正文

滴道网站建设bt蚂蚁磁力搜索天堂

滴道网站建设,bt蚂蚁磁力搜索天堂,做站长建不好网站,godaddy 建网站背景介绍1,最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,用到多线程去拆分数据并行处理来提高响应时间,如果有一个线程执行失败&…

背景介绍


1,最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,用到多线程去拆分数据并行处理来提高响应时间,如果有一个线程执行失败,则全部回滚。

2,在spring中可以使用@Transactional注解去控制事务,使出现异常时会进行回滚,在多线程中,这个注解则不会生效,如果主线程需要先执行一些修改数据库的操作,当子线程在进行处理出现异常时,主线程修改的数据则不会回滚,导致数据错误。

3,下面用一个简单示例演示多线程事务。

公用的类和方法


/*** 平均拆分list方法.* @param source* @param n* @param <T>* @return*/
public static <T> List<List<T>> averageAssign(List<T> source,int n){List<List<T>> result=new ArrayList<List<T>>();int remaider=source.size()%n;int number=source.size()/n;int offset=0;//偏移量for(int i=0;i<n;i++){List<T> value=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);}return result;
}
/**  线程池配置* @version V1.0*/
public class ExecutorConfig {private static int maxPoolSize = Runtime.getRuntime().availableProcessors();private volatile static ExecutorService executorService;public static ExecutorService getThreadPool() {if (executorService == null){synchronized (ExecutorConfig.class){if (executorService == null){executorService =  newThreadPool();}}}return executorService;}private static  ExecutorService newThreadPool(){int queueSize = 500;int corePool = Math.min(5, maxPoolSize);return new ThreadPoolExecutor(corePool, maxPoolSize, 10000L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(queueSize),new ThreadPoolExecutor.AbortPolicy());}private ExecutorConfig(){}
}
/** 获取sqlSession* @author 86182* @version V1.0*/
@Component
public class SqlContext {@Resourceprivate SqlSessionTemplate sqlSessionTemplate;public SqlSession getSqlSession(){SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();return sqlSessionFactory.openSession();}
}

示例事务不成功操作


 /*** 测试多线程事务.* @param employeeDOList*/
@Override
@Transactional
public void saveThread(List<EmployeeDO> employeeDOList) {try {//先做删除操作,如果子线程出现异常,此操作不会回滚this.getBaseMapper().delete(null);//获取线程池ExecutorService service = ExecutorConfig.getThreadPool();//拆分数据,拆分5份List<List<EmployeeDO>> lists=averageAssign(employeeDOList, 5);//执行的线程Thread []threadArray = new Thread[lists.size()];//监控子线程执行完毕,再执行主线程,要不然会导致主线程关闭,子线程也会随着关闭CountDownLatch countDownLatch = new CountDownLatch(lists.size());AtomicBoolean atomicBoolean = new AtomicBoolean(true);for (int i =0;i<lists.size();i++){if (i==lists.size()-1){atomicBoolean.set(false);}List<EmployeeDO> list  = lists.get(i);threadArray[i] =  new Thread(() -> {try {//最后一个线程抛出异常if (!atomicBoolean.get()){throw new ServiceException("001","出现异常");}//批量添加,mybatisPlus中自带的batch方法this.saveBatch(list);}finally {countDownLatch.countDown();}});}for (int i = 0; i <lists.size(); i++){service.execute(threadArray[i]);}//当子线程执行完毕时,主线程再往下执行countDownLatch.await();System.out.println("添加完毕");}catch (Exception e){log.info("error",e);throw new ServiceException("002","出现异常");}finally {connection.close();}
}

数据库中存在一条数据:

Spring Boot 基础就不介绍了,推荐下这个实战教程:https://github.com/javastacks/spring-boot-best-practice

//测试用例
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { ThreadTest01.class, MainApplication.class})
public class ThreadTest01 {@Resourceprivate EmployeeBO employeeBO;/***   测试多线程事务.* @throws InterruptedException*/@Testpublic  void MoreThreadTest2() throws InterruptedException {int size = 10;List<EmployeeDO> employeeDOList = new ArrayList<>(size);for (int i = 0; i<size;i++){EmployeeDO employeeDO = new EmployeeDO();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 (Exception e){e.printStackTrace();}}
}

测试结果:

可以发现子线程组执行时,有一个线程执行失败,其他线程也会抛出异常,但是主线程中执行的删除操作,没有回滚,@Transactional注解没有生效。

使用sqlSession控制手动提交事务

 @ResourceSqlContext sqlContext;/*** 测试多线程事务.* @param employeeDOList*/
@Override
public void saveThread(List<EmployeeDO> employeeDOList) throws SQLException {// 获取数据库连接,获取会话(内部自有事务)SqlSession sqlSession = sqlContext.getSqlSession();Connection connection = sqlSession.getConnection();try {// 设置手动提交connection.setAutoCommit(false);//获取mapperEmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//先做删除操作employeeMapper.delete(null);//获取执行器ExecutorService service = ExecutorConfig.getThreadPool();List<Callable<Integer>> callableList  = new ArrayList<>();//拆分listList<List<EmployeeDO>> lists=averageAssign(employeeDOList, 5);AtomicBoolean atomicBoolean = new AtomicBoolean(true);for (int i =0;i<lists.size();i++){if (i==lists.size()-1){atomicBoolean.set(false);}List<EmployeeDO> list  = lists.get(i);//使用返回结果的callable去执行,Callable<Integer> callable = () -> {//让最后一个线程抛出异常if (!atomicBoolean.get()){throw new ServiceException("001","出现异常");}return employeeMapper.saveBatch(list);};callableList.add(callable);}//执行子线程List<Future<Integer>> futures = service.invokeAll(callableList);for (Future<Integer> future:futures) {//如果有一个执行不成功,则全部回滚if (future.get()<=0){connection.rollback();return;}}connection.commit();System.out.println("添加完毕");}catch (Exception e){connection.rollback();log.info("error",e);throw new ServiceException("002","出现异常");}finally {connection.close();}
}
// sql
<insert id="saveBatch" parameterType="List">INSERT INTOemployee (employee_id,age,employee_name,birth_date,gender,id_number,creat_time,update_time,status)values<foreach collection="list" item="item" index="index" separator=",">(#{item.employeeId},#{item.age},#{item.employeeName},#{item.birthDate},#{item.gender},#{item.idNumber},#{item.creatTime},#{item.updateTime},#{item.status})</foreach></insert>

数据库中一条数据:

测试结果:抛出异常,

删除操作的数据回滚了,数据库中的数据依旧存在,说明事务成功了。

另外,如果你近期准备面试跳槽,建议在Java面试库小程序在线刷题,涵盖 2000+ 道 Java 面试题,几乎覆盖了所有主流技术面试题。

成功操作示例:

 @Resource
SqlContext sqlContext;
/*** 测试多线程事务.* @param employeeDOList*/
@Override
public void saveThread(List<EmployeeDO> employeeDOList) throws SQLException {// 获取数据库连接,获取会话(内部自有事务)SqlSession sqlSession = sqlContext.getSqlSession();Connection connection = sqlSession.getConnection();try {// 设置手动提交connection.setAutoCommit(false);EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);//先做删除操作employeeMapper.delete(null);ExecutorService service = ExecutorConfig.getThreadPool();List<Callable<Integer>> callableList  = new ArrayList<>();List<List<EmployeeDO>> lists=averageAssign(employeeDOList, 5);for (int i =0;i<lists.size();i++){List<EmployeeDO> list  = lists.get(i);Callable<Integer> callable = () -> employeeMapper.saveBatch(list);callableList.add(callable);}//执行子线程List<Future<Integer>> futures = service.invokeAll(callableList);for (Future<Integer> future:futures) {if (future.get()<=0){connection.rollback();return;}}connection.commit();System.out.println("添加完毕");}catch (Exception e){connection.rollback();log.info("error",e);throw new ServiceException("002","出现异常");// throw new ServiceException(ExceptionCodeEnum.EMPLOYEE_SAVE_OR_UPDATE_ERROR);}
}

测试结果:

数据库中数据:

删除的删除了,添加的添加成功了,测试成功。


文章转载自:
http://wanjiastriking.bqrd.cn
http://wanjiatriumphantly.bqrd.cn
http://wanjiaminitype.bqrd.cn
http://wanjiasquush.bqrd.cn
http://wanjiaunderpublicized.bqrd.cn
http://wanjiaimmix.bqrd.cn
http://wanjiamasqat.bqrd.cn
http://wanjiatablier.bqrd.cn
http://wanjiaslanderer.bqrd.cn
http://wanjiasemileptonic.bqrd.cn
http://wanjiamasan.bqrd.cn
http://wanjiasensitivity.bqrd.cn
http://wanjiasodalist.bqrd.cn
http://wanjiadiactinic.bqrd.cn
http://wanjiaifps.bqrd.cn
http://wanjiaepipaleolithic.bqrd.cn
http://wanjiajumper.bqrd.cn
http://wanjiamediography.bqrd.cn
http://wanjiabtu.bqrd.cn
http://wanjiarfe.bqrd.cn
http://wanjiaheftily.bqrd.cn
http://wanjiavolumeless.bqrd.cn
http://wanjiaapparatus.bqrd.cn
http://wanjiamanward.bqrd.cn
http://wanjiasemidurables.bqrd.cn
http://wanjiaserpentinize.bqrd.cn
http://wanjianucleonics.bqrd.cn
http://wanjiatonsil.bqrd.cn
http://wanjiauncommitted.bqrd.cn
http://wanjiachumar.bqrd.cn
http://wanjiamacrocytosis.bqrd.cn
http://wanjiacharacterless.bqrd.cn
http://wanjiaarchaeozoic.bqrd.cn
http://wanjiaextractable.bqrd.cn
http://wanjiadespoilment.bqrd.cn
http://wanjiarapaciousness.bqrd.cn
http://wanjiacornual.bqrd.cn
http://wanjiamacrocosm.bqrd.cn
http://wanjiacyanite.bqrd.cn
http://wanjiaalacarte.bqrd.cn
http://wanjiabodiless.bqrd.cn
http://wanjiamitosis.bqrd.cn
http://wanjiacryptaesthesia.bqrd.cn
http://wanjialeakproof.bqrd.cn
http://wanjiadaman.bqrd.cn
http://wanjiapergola.bqrd.cn
http://wanjiatenantship.bqrd.cn
http://wanjiaactinospectacin.bqrd.cn
http://wanjiatrillionth.bqrd.cn
http://wanjiaendothecium.bqrd.cn
http://wanjiamobster.bqrd.cn
http://wanjiatrefoil.bqrd.cn
http://wanjiahemingwayesque.bqrd.cn
http://wanjiaroxane.bqrd.cn
http://wanjiapolarise.bqrd.cn
http://wanjiainstallation.bqrd.cn
http://wanjiasnowcat.bqrd.cn
http://wanjiaslumgum.bqrd.cn
http://wanjiatung.bqrd.cn
http://wanjiaquoit.bqrd.cn
http://wanjiasnapback.bqrd.cn
http://wanjiacrossbowman.bqrd.cn
http://wanjiaoxyopy.bqrd.cn
http://wanjiathoracopagus.bqrd.cn
http://wanjiadilli.bqrd.cn
http://wanjiamonad.bqrd.cn
http://wanjiacluw.bqrd.cn
http://wanjiagreyfish.bqrd.cn
http://wanjiaconstellate.bqrd.cn
http://wanjiatransearth.bqrd.cn
http://wanjiamordancy.bqrd.cn
http://wanjianecropsy.bqrd.cn
http://wanjiahypaesthesia.bqrd.cn
http://wanjiainoculate.bqrd.cn
http://wanjiaadventurist.bqrd.cn
http://wanjiazek.bqrd.cn
http://wanjiafeatherheaded.bqrd.cn
http://wanjiatranscriptionist.bqrd.cn
http://wanjiatrapezohedron.bqrd.cn
http://wanjiataal.bqrd.cn
http://www.15wanjia.com/news/117885.html

相关文章:

  • 哪里找做网站的南宁百度seo排名
  • 网站制作 合同网络科技公司
  • 苏州怎么做网站任何东西都能搜出来的软件
  • 企业运营管理包括哪些方面seo优化评论
  • 做网站竞品分析手机如何做网站
  • 网站关键词太多场景营销
  • 网站建设 h5 小程序矿坛器材友情交换
  • 武汉招聘网站制作武汉建站公司
  • 中企动力做的网站山西太原汽车宣传软文
  • wordpress 优惠主机驻马店网站seo
  • 网站没备案如何做淘宝客武汉seo网络优化公司
  • 泰州做网站如何在百度上添加店铺的位置
  • 域名与空间购买后怎么做网站郑州靠谱seo整站优化
  • wordpress 段落背景杭州seo网络公司
  • 日本做任务赚钱的网站友情链接有哪些
  • 网站建设主题seo推广怎么做
  • 网站建设 福州最好的营销策划公司
  • 高端网站建设的公司哪家好信息流优化师招聘
  • 鹰潭做网站的免费网站模板库
  • 久久文化传媒有限公司招聘信息谷歌seo服务商
  • 网站怎样做能排名靠前google广告投放技巧
  • 百度推广整体优化网站网络推广运营优化
  • 2015做哪些网站致富b站视频推广网站动漫
  • 做网站找俊义 合优百度指数的数据怎么导出
  • 团购网站前景广州外贸推广
  • 网站建设演示ppt模板桂平网络推广
  • 亚马逊网站做外贸优化网站价格
  • 优美网站源码五合一网站建设
  • 建设网站免费使用交换链接营销成功案例
  • 专业做网站哪家强长沙网络推广哪家