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

支付宝一面多线程事务怎么回滚?用Transactional可以回去了!

  背景介绍
  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();     } }
  另外,如果你近期准备面试跳槽,建议在 Java面试库小程序在线刷题,涵盖 2000+ 道 Java 面试题,几乎覆盖了所有主流技术面试题。  示例事务不成功操作  /**  * 测试多线程事务.  * @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}          )        
  数据库中一条数据:
  测试结果:抛出异常,
  删除操作的数据回滚了,数据库中的数据依旧存在,说明事务成功了。
  另外,如果你近期准备面试跳槽,建议在 Java面试库小程序在线刷题,涵盖 2000+ 道 Java 面试题,几乎覆盖了所有主流技术面试题。
  成功操作示例:   @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);     } }
  测试结果:
  数据库中数据:
  删除的删除了,添加的添加成功了,测试成功。
  原文链接:https://blog.csdn.net/weixin_43225491/article/details/117705686

曹丕继位后,是怎么隐诛曹彰的?223年,魏文帝曹丕与弟弟曹彰正在母亲卞太后寝宫内下棋助兴。不料,曹彰突然倒地不起,捂着肚子一脸痛苦的指着案几上的一盘枣,问道王兄,为何如此。曹丕不屑一笑现在你还想知道玺绶在哪吗?1947年,5名高级干部遇袭牺牲,毛主席震怒枪毙骑兵连的指导员1947年5月,解放军翼东军分区代表团一行人在柴胡子村被一群土匪偷袭围攻,我军五名高级干部因此牺牲。噩耗传到延安后,大家悲愤异常,坚决要讨回公道。这时,毛主席却下令枪毙负责警卫工作崇祯把魏忠贤一杀,为何大明就垮台了?王承恩说了一句很中肯的话忠贤本市井无赖,中年净身,纵入内地,初犹谬为小忠小信以幸恩,继乃敢为大奸大恶以乱政。杨涟众所周知,在明朝的历史上奸臣宦官很多,而其中最出名的莫过于九千岁魏忠贤。巅峰时期的魏忠贤把持溥仪的贴身侍卫不仅作恶多端,还睡过正宫娘娘,最后毙于刑场在中国近代历史的征程中,有这样一个人物,他年仅三岁就被抱上了皇位,是清朝登基皇帝中年龄最小的一位,国家沦陷时,他被迫退位,成为了中国的最后一位皇帝,这个人就是爱新觉罗溥仪。辛亥革命重新解读历史,你会发现曹操才是汉朝真正的忠臣头条中国史曹操是我们在三国里最熟悉的一位枭雄。他的政治军事,才能也是三国时代数一数二的。历史上对曹操的评价褒贬不一。他出生于宦官家庭,他的父亲是曹崇是东汉宦官曹腾的养子,导致了曹操350万人口国家,走出皇马巴萨主力!总价4亿,国足的69倍英超西甲意甲等欧洲主流联赛暂停,FIFA比赛日隆重登场。这是2022年世界杯之前,各大豪门劲旅珍贵的磨合热身机会。9月20日,乌拉圭国家队球员汇合,引发球迷的关注西甲豪门皇马的当红瑞信2021年全球财富增长41万亿美元,中国贡献四分之一记者辛圆瑞信研究院周二发布的全球财富报告称,2021年全球财富总额是有记录以来增长最快的一年。不过,受通胀利率上升以及资产价格回落等因素影响,财富增长在2022年可能会发生逆转。根学猫叫吮手指裸体穿围裙,这些油腻男星贡献的名场面当代油腻男明星真是层出不穷,一波油腻男过去了又来一波,观众看到他们就仿佛把自己浸泡在了油中,一遍又一遍地对自己反复油炸。1张翰新晋油腻男张翰,他在自编自导自演的东八区的先生们里面表2022年养老金计发基数密集发布部分人养老金会变多中新网9月21日电(记者李金磊)近期,2022年养老金计发基数密集发布,这项数据发布之后,部分人的养老金会进行重算而变多,怎么回事?多地发布2022年养老金计发基数据中新财经不完全灵活就业人员社保基数高于个人缴费基数下限的不用补缴,是真的吗点击上方蓝色按钮,可同步收听全文精彩内容临近十月,网上有关灵活就业人员社保补缴一大笔钱的消息很多,有灵活就业人员咨询,9月起,听说灵活就业人员要从1月起补缴一笔社保费,这到底是真的突发!又有A股董事长被查,并采取留置措施!股价大跌,3000亿巨头紧急回应中国基金报安曼今晚,大家都在静等美联储公布9月利率决议。基金君带大家来看几个国内的财经新闻。21日晚间,经了解,公司同日收到了据了解。楚天龙的主要产品为以金融社保卡标准银行IC卡等
在快手,嗅年味撰文文烨豪编辑吴先之尽管年味越来越淡已经成为近两年大众语境的共识,但在线上又是另一番局面。随着新年越来越近,不少App图标都穿上了新衣,各互联网平台的春节活动也已步入白热化阶段。而年景走,春节去南华泡黑泥温泉2023年春节即将来临,你是否也想去一个有风的地方看山看水看风景,听风听雨听明月?这个春节假期,不如来楚雄南华黑泥温泉,感受不一样的年味。楚雄州南华黑泥温泉位于南华县一街乡团山村委辽宁男篮完败广东男篮的原因找到了2023年1月18日,号称CBA春晚的辽粤大战如期进行了,通过一场全方面全过程全员性的完败,辽宁男篮如愿输掉了本场比赛。很多辽宁老球迷都知道,辽宁队有个特点,就是愿意给人惊喜,尤其这个春节,我们一起去白沙!后疫情时代,白沙作为全国休闲农业与乡村旅游示范点,开启了新的征途。春节前后,随着旅游业市场不断调整适配,短途游日渐红火,白沙成为家庭休闲娱乐亲子游玩品尝特色美食的首选之地。小编捋出中国足球烂到根部,媒体人圈内都知道刘奕有问题,但没人敢说李铁被带走后,紧接着中国足球协会第十一届执委会成员原秘书长刘奕也被带走了,另外中国足协常务副秘书长兼国管部部长陈永亮也接受了审查,事实说明,这件事背后的大人物还没有被挖出。斗胆猜测澳网丨14次征战大满贯终进16强,29岁的中国金花朱琳大器晚成突破自我钱江晚报小时新闻记者曹林波北京时间1月20日晚,在2023年澳网女单第三轮的一场焦点大战中,中国金花朱琳苦战三盘,鏖战至墨尔本当地时间接近凌晨2点,最终76(3)1664击败了世界诺基亚C12手机发布IT之家1月19日消息,HMDGlobal在2023年推出了一款廉价的Android12Go版手机诺基亚C12。诺基亚C12搭载了6。3英寸HD分辨率的LCD显示屏,机身尺寸为16璀璨濠江多元韵味绘芳华大三巴是澳门最受欢迎的景点之一。欧家威,澳门广州社团总会副会长澳门工商联会理事长。无论是米其林星级餐厅,还是街边的手推车小食,都演绎出澳门的美食气质。何东图书馆。品尝美味是澳门旅游自然论文格陵兰冰盖20012011年比20世纪平均高1。5C中新网北京1月19日电(记者孙自法)国际著名学术期刊自然最新发表一篇气候变化研究论文指出,对公元1100年至2011年格陵兰中北部的温度重建显示,格陵兰冰盖的近期温度是过去1000编辑说湖南少儿出版社开启一场从自然百科到历史人文的美妙旅程中国国家地理手绘百科视频加载中一套给孩子的中国文化中国历史大画卷,开启一场从自然百科到历史人文的美妙旅程。青藏高原上,让欧洲植物猎人为之疯狂的美丽植物是什么?明明不起眼的胡椒,在西方竟然曾经和黄金一样赏年俗看年戏美心红酒小镇举办特色村晚活动现场。杨孝永摄1月19日,由涪陵区文化和旅游发展委员会区农业农村委员会蔺市街道办事处指导,蔺市街道泡桐村主办,蔺市街道文化服务中心蔺市街道新时代文明实践所协办,美心红酒小镇景区