范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

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

  背景介绍
  1.最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,用到多线程去拆分数据并行处理来提高响应时间,如果有一个线程执行失败,则全部回滚。
  2.在spring中可以使用@Transactional注解去控制事务,使出现异常时会进行回滚,在多线程中,这个注解则不会生效,如果主线程需要先执行一些修改数据库的操作,当子线程在进行处理出现异常时,主线程修改的数据则不会回滚,导致数据错误。
  3.下面用一个简单示例演示多线程事务。 公用的类和方法/**  * 平均拆分list方法.  * @param source  * @param n  * @param   * @return  */ public static  List> averageAssign(List source,int n){     List> result=new ArrayList>();     int remaider=source.size()%n;      int number=source.size()/n;      int offset=0;//偏移量     for(int i=0;i 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 {     @Resource     private SqlSessionTemplate sqlSessionTemplate;      public SqlSession getSqlSession(){         SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();         return sqlSessionFactory.openSession();     } } 示例事务不成功操作/**  * 测试多线程事务.  * @param employeeDOList  */ @Override @Transactional public void saveThread(List employeeDOList) {     try {         //先做删除操作,如果子线程出现异常,此操作不会回滚         this.getBaseMapper().delete(null);         //获取线程池         ExecutorService service = ExecutorConfig.getThreadPool();         //拆分数据,拆分5份         List> 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 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  employeeDOList = new ArrayList<>(size);         for (int i = 0; i employeeDOList) throws SQLException {     // 获取数据库连接,获取会话(内部自有事务)     SqlSession sqlSession = sqlContext.getSqlSession();     Connection connection = sqlSession.getConnection();     try {         // 设置手动提交         connection.setAutoCommit(false);         //获取mapper         EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);         //先做删除操作         employeeMapper.delete(null);         //获取执行器         ExecutorService service = ExecutorConfig.getThreadPool();         List> callableList  = new ArrayList<>();         //拆分list         List> lists=averageAssign(employeeDOList, 5);         AtomicBoolean atomicBoolean = new AtomicBoolean(true);         for (int i =0;i list  = lists.get(i);             //使用返回结果的callable去执行,             Callable callable = () -> {                 //让最后一个线程抛出异常                 if (!atomicBoolean.get()){                     throw new ServiceException("001","出现异常");                 }               return employeeMapper.saveBatch(list);             };             callableList.add(callable);         }         //执行子线程        List> futures = service.invokeAll(callableList);         for (Future 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 INTO  employee (employee_id,age,employee_name,birth_date,gender,id_number,creat_time,update_time,status)  values            (      #{item.employeeId},      #{item.age},      #{item.employeeName},      #{item.birthDate},      #{item.gender},      #{item.idNumber},      #{item.creatTime},      #{item.updateTime},      #{item.status}          )        
  数据库中一条数据:
  测试结果,抛出异常:
  删除操作的数据回滚了,数据库中的数据依旧存在,说明事务成功了。
  成功操作示例: @Resource SqlContext sqlContext; /**  * 测试多线程事务.  * @param employeeDOList  */ @Override public void saveThread(List 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> callableList  = new ArrayList<>();         List> lists=averageAssign(employeeDOList, 5);         for (int i =0;i list  = lists.get(i);             Callable callable = () -> employeeMapper.saveBatch(list);             callableList.add(callable);         }         //执行子线程        List> futures = service.invokeAll(callableList);         for (Future 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);     } }
  测试结果:
  数据库中数据:
  删除的删除了,添加的添加成功了,测试成功。
  来源:blog.csdn.net/weixin_43225491/article/details/117705686

阿里达摩院大模型M6带头人杨红霞已离职个人选择,非行业原因作者李梅(AI科技评论)编辑AeneasDavid新智元导读阿里M6大模型带头人杨红霞,已从阿里巴巴达摩院智能计算实验室离职。AI科技评论获悉,阿里M6大模型的原带头人杨红霞,已于百元蒲公英X3A体验报告千兆智能组网远程控制响应国家号召,单位还是搬到了郊区办公,随之而来的问题就是办公时间的缩短,为了能够每天回家就不得不把部分工作带到家里去完成,这样就需要能够在家里实现对单位电脑的远程开关和控制。其实实台湾记者问古月你什么时候能去台湾?古月回答后,全场掌声雷动图丨古月前言众所周知,毛主席是一位极具幽默风格的伟人,他的寥寥数语便能使人开腹大笑。有关毛主席风趣幽默的故事,大家一定都有所耳闻,今天就不多提了。但是,在影坛上扮演毛主席的特型演员女叛徒随老蒋败退台湾,晚年回国探亲,老友一句话说得她哑口无言在阅读此文之前,麻烦您点击一下关注,既方便您进行讨论与分享,又给您带来不一样的参与感,感谢您的支持!自中国共产党成立以来,无数仁人志士为了新中国的建立付出了宝贵的青春甚至生命,在这苹果不想改用C口充电,iPhone未来计划无端口设计,学习魅族?在欧盟的要求下,所有科技厂商必须在2024年完成整改,统一使用TypeC充电标准,苹果也要放弃坚持十年的Lighting接口。报告显示,欧盟规定可能让苹果每年损失百亿利润,库克为此日本失落的二十年到底失去了什么?自从1980年代末起日本泡沫经济以来,全球主流媒体一致唱衰该国经济,称过去的20年为日本失落的20年。然而如果我们平心而论,日本至今依旧是世界第三大经济体,GDP高于经济合作与发展自驾逃离西藏,被困宁夏银川,两个女生只能睡在高速公路边上高速公路上流浪车子被贴封条厕所旁露营,曾经令人羡慕的西藏之旅,现在变成了一场逃难,七月进入西藏,八月爆发疫情,九月自驾青藏线离开,一路上的经历太魔幻了,至今回想依然觉得像一场梦一般日本经济界人士经贸合作是中日关系的压舱石和推进器今年是中日邦交正常化50周年的年份,中日双方在政经等各个层面举行了多项纪念活动,表达了对推动中日关系沿着正确轨道健康稳定发展构筑契合新时代要求的中日关系的期待。9月12日,不忘初心西藏梅里神山日本登山队17人全部遇难,现场录音至今未敢公布梅里雪山,位于西藏察隅县东部与云南迪庆藏族自治州德钦县境云岭乡西部,是一座南北走向的庞大雪山群。其主峰卡瓦格博,是云南第一高峰,也是世界公认的最美雪山,被誉为雪山之神。千百年来,当早安崭新的一天,愿你与美好不期而遇太阳早安今天太阳今天是2022年10月11日,星期二,农历九月十六新的一天,让我们迎着清晨的第一缕阳光,怀揣梦想,微笑前行。愿有缘相遇的每一个人平安快乐,幸福美满,所求皆如意,所行日本火箭发射失败后为何要自毁?航天技术专家解读环球时报综合报道据日媒报道,12日日本小型火箭埃普西隆6号发射失败后,收到自毁指令。航天技术专家黄志澄对环球时报记者表示,日本国土面积比较小,若不自毁,火箭可能会对地面设施和人员构
四川华新川陴郫县豆瓣联合淘特发起全国首个厂小二课程图说3月17日,四川华新川陴郫县豆瓣联合淘特发起的全国首个厂小二课程在成都上线。上线3年,产业直供电商淘特探索的M2C(制造直连消费)模式,又有新的进展。3月17日,记者从四川华新第六届镇江高新区杯创新创业大赛颁奖仪式举行原标题第六届镇江高新区杯创新创业大赛颁奖仪式举行(主题)集聚高层次科技人才打造闪亮双创名片(副题)金山网讯(通讯员王璧瑢记者姜萍)3月16日下午,镇江高新区举行第六届镇江高新区杯创任正非美国制裁期间华为完成1。3万颗器件的开发手机中国新闻近日,手机中国注意到,上海交通大学发布了一篇文章擦亮花火共创未来任正非在难题揭榜花火奖座谈会上的讲话的文章。其中,透露出了不少值得关注的信息,感兴趣的网友可以来关注一下盘点新千年以来中国体育十大现象级成就近几年来,中国体育似乎进入了万马齐喑的至暗时刻,星光黯淡,乏善可陈,让人无比怀念那些星光璀璨高潮迭起的光辉岁月,让我们一起盘点新千年后中国体育的高光时刻。1。中国男足冲出亚洲,走向足坛3大事件升级!曝出共19人被带走吴兴涵没说谎,戴琳也怂了中超联赛在金元时代出现了严重泡沫,如今泡沫破裂,所有俱乐部和球员都出现了困境,大批球员开启讨薪模式,部分俱乐部顶不住直接解散退出了。各级联赛全面洗牌,球员也面临洗牌,这些巨变背后的提供160座充电桩!珠海出租车服务区向社会车辆开放南都讯据珠海交通近日发布消息,广东省公布的首批示范性出租车综合服务区名单中,珠海市有三个新能源汽车充电站入选。这三个充电站分别位于珠海南湾竹仙洞公园旁前山岐关工业大厦以及金湾区海澄8个免费好用的微信小程序,个个都是精品,请你低调使用现在的手机App体积越来越大了,不妨把目光转移到微信小程序上。今天给大家推荐8个免费好用的微信小程序,个个都是精品,请你低调使用。01。桌面翻页时钟特点让手机全屏显示时间。一款极简巴萨皇社,知道我的苦了吗?踢老穆的球队,让你知道社会的残酷巴萨皇社,现在你知道我的苦了吗?你踢这白头发老头的球队,就知道社会的残酷了,不说了,都是眼泪!穆里尼奥我主场进你两个,你主场进我一个,算我输!皇社我都直接踢人了,还能怎么办!欧联杯福州三宝城南公河口街区二期主体建筑基本完工展示繁华商贸再现市井生活三宝城南公河口街区二期主体建筑基本完工漫步打铁港公园感受水清岸绿,走过万寿桥,在南公河口街区品尝一杯香浓咖啡,再通过林荫小道踏入南公园欣赏假山美景,这样的场浙能在疆5个新能源项目全面复工挖掘风光向大西北进发浙能在疆能源项目莎车100兆瓦光伏项目组件安装现场。通讯员尉晓飞供图3月15日上午,新疆克拉玛依市乌尔禾区的气温在2摄氏度,建设工地尚有寒意。当天,浙能集团旗下浙江新能控股的乌尔禾徐寅生姚明纷纷捧场,这个上海的社区市民健身中心有何特别?3月17日下午,位于零陵北路的斜土社区市民健身中心内,打乒乓球练瑜伽跑步机健身一派热火朝天的运动场景。当天,以日晖跃动为名的斜土社区市民健身中心全新改建后正式启用。作为斜土社区的居