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

支付宝一面多线程事务怎么回滚?用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

游戏少年的成长登贝莱今天故事的主人公是曾经的天才少年奥斯曼登贝莱问题少年游戏王子,训练迟到,浪费天赋等等,一系列的问题词汇都出现在他的身上。在哈维没有回归巴萨执教的时候,天价的香球王已经沦为了替补球员乒乓球的那些事之一N年前的夏季,市里成立了乒乓球俱乐部,活动场所在江北火车头体育馆,全城的爱好者都集中在这里,我也在那年调回家门口工作,被他们的活动吸引,便拿起了球拍。当时,人们从野路子来,向着规范体育大观之武术(二)枪术一枪术枪术是以枪为器械的武术练习。按枪的种类,有大枪花枪二头枪等之分,使用上则均以拦拿扎为主。二枪法拦枪和拿枪又称圈枪,是防御之法,用时圈小迅速准确有力。扎枪是进攻之法,有上平中平施罗德舍8400要260,但湖人就赚了吗?对着镜头,戴着墨镜,丹尼斯施罗德咬住了欧锦赛的铜牌。他有资格这么开心,因为那是他由亲手赢下,自2005年以来德国男篮在欧锦赛上拿到的第一枚奖牌。在8场欧锦赛里,施罗德场均能拿到22世体主编拜仁意识到他们犯错了,马内很出色但不是莱万那种杀手直播吧9月21日讯世界体育报主编FrancescAguilar今天在推特发文,他表示拜仁在寻找莱万多夫斯基的替代者方面做错了。这位主编写道拜仁开始意识到,他们在寻找莱万的替代者时犯B威廉姆斯马奎尔每天都全力以赴训练,C罗会和所有人交流在接受thesportsman的专访时,曼联小将布兰登威廉姆斯谈到了马奎尔和C罗。他表示,马奎尔每天都会全力以赴地投入训练,C罗则给了他很多的建议,也非常擅于和队友沟通。关于马奎尔除了小行星撞地球和火山喷发恐龙蛋研究发现恐龙灭绝新因素用于本次研究的采自陕西山阳盆地的1件恐龙蛋化石标本。中新社记者孙自法摄中新网北京9月20日电(记者孙自法)从2。35亿年前的晚三叠世出现到6600万年前的白垩世消失,恐龙在地球上存马斯克地球经济远未达到物理极限科学杂志自然(Nature)最近在推特上分享了一份回顾1972年罗马俱乐部增长的极限(LimitstoGrowth)报告的新分析,认为经济扩张不可能不受阻碍地继续下去,物理限制可能外媒述评世界看好中国经济发展前景据英国泰晤士报网站9月17日报道,中国公布的8月份经济数据显示,中国经济表现出惊人韧性。数据表明,作为世界第二大经济体,中国经济步伐正在加速,从而提升了经济复苏的前景。最近的乐观数阿德正式决定退役,太阳打算交易克劳德!霍华德和快船互相有意过去的一夜NBA又发生了不少事情,涉及了太阳爵士76人快船勇士湖人等多支球队。我给大家专门做了汇总,一起来看一下吧!1换1太阳打算交易克劳德名记文胖在今天参加节目时表示太阳队目前已楼市回暖要失约,曹德旺预言成真?41家庭将面临什么结果?根据最新数据显示,70个大中城市中,不管是新房还是二手房,下跌的城市均已超过70,即便是一线城市,上海的房价环比上涨仅0。6,北京0。4,广州和深圳环比是下跌的,按照这个趋势来看,
5家半导体企业科创板IPO进展披露近日,高华科技派瑞特气颀中科技南芯科技中科飞测等多家半导体公司科创板IPO申请迎来新的进展,证监会同意上述企业注册申请。派瑞特气2月28日,证监会披露了关于同意中船(邯郸)派瑞特种郭台强的印度梦还好吗?苹果充电线供应商正崴印度厂烧了3小时自苹果公司2017年开始与印度政府合作以来,到印度砸重金的数家台商今年状况频出,不是员工骚乱就是食物中毒,更可怕的是祝融光临,一切努力白费。iPhone充电线供应商正崴印度厂2月2华为起诉小米专利侵权的背后,则是华为构建技术壁垒的野心近日,华为正式起诉小米专利侵权,侵权内容为发送控制信令的方法和装置载波聚合时反馈ACKNACK信息的方法基站和用户设备一种获取全景图像的方法及终端一种锁屏方法及移动终端。对于两个科华为nova10青春版手机发布搭载骁龙6804G芯片,1699元起IT之家3月3日消息,华为nova10青春版手机正式发布,首发价1699元起,今晚开启预售。华为nova10青春版手机拥有幻夜黑冰晶蓝两款配色,采用6。78英寸LCD居中打孔屏,拥华为nova10青春版上架搭载骁龙680起售价有望低于1999近日,一款名为华为nova10青春版的新机悄然上架。该机在外观方面和nova10SE相差不大,核心处理器依旧是骁龙680,采用台积电6nm工艺。最大的变化点是屏幕由6。67英寸变为水滴筹1月拦截418例不合规筹款申请中新经纬3月2日电近日,水滴筹透明运营委员会公布2023年1月筹款案例的审查工作情况。当月,水滴筹拦截并驳回了418例不合规的筹款申请,并在成功发起申请后,对每一例进行中的筹款二次徐凤辉就业新趋势为就业市场带来机会,也有多重性经济复苏,劳动力市场需求旺盛。兔年春节刚刚过完,多地政府便亲身上阵,上演抢人大潮,大年初四,苏州市人社局吴江区人社局当地重点企业国有人力资源企业等组成的劳务招聘小分队,组团到河南抢奔驰举行第十届中国可持续发展对话会2月27日北京今日,梅赛德斯奔驰举办第十届中国可持续发展对话会,并宣布在动力电池闭环回收领域同本土伙伴展开合作。学术界商界和行业协会等各界人士参加了本届以推动产业转型赋能绿色发展为多方发力推动消费回暖消费既是国民经济循环的终点,也是起点,是拉动经济增长的三驾马车之一,在构建新发展格局中作用举足轻重。2022年底召开的中央经济工作会议将着力扩大国内需求作为2023年重点工作任务之力聚热能拟冲刺上交所主板IPO上市,预计投入募资15。36亿元,近年来主业毛利率走低3月1日,浙江力聚热能装备股份有限公司递交首次公开发行股票招股说明书(申报稿)。据此,该公司拟冲刺上交所主板IPO上市。本次公开发行不超过2275万股,不低于本次发行后总股本的25不再遮遮掩掩!房价上涨几乎成了2023年公开的明牌2023房价是涨是跌?到底要不要买房?几乎是每个老百姓都关注或者绕不开的问题。经历了2022年楼市断崖式下跌后,2022年下半年起频出不断的调控利好政策将2023年的楼市政策再次带