多线程异步处理时的事务管理
分布式事务介绍:https://zhuanlan.zhihu.com/p/183753774
前言:项目中在保证数据一致性的前提下还想提高执行效率,有什么好办法么?使用多线程肯定是首先想到的,但多线程之间的事务怎么保持一致呢?下面的代码就是在单个项目中使用多线程异步处理时的事务管理的方法。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;/*** 多线程异步处理时的事务管理* 1.addFunction 添加要异步执行的方法* 2.execute方法中,使用全局的计数器和异常标记字段,统计个异步线程执行的结果* 当所有异步线程执行完之后,根据异常标记字段判断是回滚还是提交事务。*/
public class MultiThreadTransactionComponent {Logger logger= LoggerFactory.getLogger(this.getClass());private PlatformTransactionManager platformTransactionManager;private ThreadPoolExecutor threadPoolExecutor;private List<Supplier> supplierList=new ArrayList();// 创建执行计数器private CountDownLatch countDownLatch;// 是否存在异常AtomicReference<Boolean> isError = new AtomicReference<>(false);public MultiThreadTransactionComponent(PlatformTransactionManager transactionManager,ThreadPoolExecutor threadPoolExecutor){this.platformTransactionManager=transactionManager;this.threadPoolExecutor=threadPoolExecutor;}/*** 添加要异步执行的方法程序* @param supplier*/public void addFunction(Supplier supplier){supplierList.add(supplier);}public void execute(){countDownLatch=new CountDownLatch(supplierList.size());logger.info("【多线程事务】开始...");for(Supplier supplier:supplierList){this.threadPoolExecutor.submit(new TransactionRunnable(platformTransactionManager,supplier));}try {countDownLatch.await();if(isError.get()) {logger.error("【多线程事务】多线程执行失败,事务已回滚");// 主线程抛出自定义的异常throw new RuntimeException("多线程执行失败");}logger.info("【多线程事务】多线程执行完成,事务已提交");} catch (InterruptedException e) {logger.error("多线程执行失败");// 主线程抛出自定义的异常throw new RuntimeException("多线程执行失败"+e.getMessage());}}class TransactionRunnable implements Runnable{private PlatformTransactionManager platformTransactionManager;private Supplier supplier;public TransactionRunnable(PlatformTransactionManager platformTransactionManager, Supplier supplier) {this.platformTransactionManager=platformTransactionManager;this.supplier=supplier;}@Overridepublic void run() {DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);TransactionStatus transaction = this.platformTransactionManager.getTransaction(def);try {this.supplier.get();} catch (Exception e) {//设置错误标记isError.set(true);logger.error("【多线程事务】执行失败{}",e.getMessage());}countDownLatch.countDown();try{countDownLatch.await();if(isError.get()){// logger.info("【多线程事务-子线程】事务回滚");//事务回滚platformTransactionManager.rollback(transaction);}else {// logger.info("【多线程事务-子线程】事务提交");//事务提交platformTransactionManager.commit(transaction);}}catch (InterruptedException e){e.printStackTrace();}}}}
使用示例:
@AutowiredPlatformTransactionManager platformTransactionManager;@Autowiredprivate ThreadPoolExecutor threadPoolExecutor;@Testpublic void testTransaction(){MultiThreadTransactionComponent mttc = new MultiThreadTransactionComponent(platformTransactionManager,threadPoolExecutor);for(int k=0;k<10;k++){int i = RandomUtils.nextInt(0, 5);int y=RandomUtils.nextInt(0,5);//添加要执行的业务代码mttc.addFunction(()->{System.out.println("当前线程:" + Thread.currentThread().getName());System.out.println(i%y); //除数为0时 执行失败MarketGeomUpLog marketGeomUpLog=new MarketGeomUpLog();marketGeomUpLog.setContent(i+"--"+y);marketGeomUpLogMapper.addLog(marketGeomUpLog);return 0;});}mttc.execute();try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}
多线程异步处理时的事务管理相关推荐
- 分析Spring事务管理原理及应用
目录 一.Spring事务管理介绍 (一)基本理论 (二)实际工作中的举例 (三)简单应用举例 二.Spring事务配置介绍 (一)Spring事务属性介绍 传播属性(传播行为)可选值说明 (二)声明 ...
- [原]unity3d之http多线程异步资源下载
郑重声明:转载请注明出处 U_探索 本文诞生于乐元素面试过程,被面试官问到AssetBundle多线程异步下载时,愣了半天,同样也被深深的鄙视一回(做了3年多u3d 这个都没用过),所以发誓要实现出来 ...
- Spring中的事务管理详解
在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...
- Spring - Java/J2EE Application Framework 应用框架 第 7 章 事务管理
第 7 章 事务管理 7.1. Spring事务抽象 Spring提供了一致的事务管理抽象.这个抽象是Spring最重要的抽象之一, 它有如下的优点: 为不同的事务API提供一致的编程模型,如JTA. ...
- java元婴期(21)----java进阶(spring(5)---事务管理AOP事务管理(全自动)spring整合Junit)
事务管理 事务:一组业务操作ABCD,要么全部成功,要么全部不成功. 特性:ACID 原子性:整体 一致性:完成 隔离性:并发 持久性:结果 隔离问题: 脏读:一个事务读到另一个事务没有提交的数据 不 ...
- Spring事务管理器分类
Spring并不直接管理事务,事实上,它是提供事务的多方选择.你能委托事务的职责给一个特定的平台实现,比如用JTA或者是别的持久机制.Spring的事务管理器可以用下表表示: 事务管理器的实例 目标 ...
- Spring框架的事务管理及应用
Spring框架简介 Spring框架是一个2003年2月才出现的开源项目,该开源项目起源自Rod Johnson在2002年末出版的<Expert One-on-One J2EE Design ...
- Spring事务管理示例JDBC
Spring事务管理示例JDBC Spring Transaction Management是Spring框架中使用最广泛且最重要的特性之一.事务管理在任何企业应用程序中都是一项微不足道的任务.我们已 ...
- spring事务管理器的作用_【面试必问】Spring中的事务管理详解
在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...
最新文章
- React-Native原理及生命周期
- vue+Mint-ui实现登录注册
- Nginx负载均衡记录
- 作者:张志恒(1990-),男,兰州大学资源环境学院硕士生。
- java中类的命名规则_java类方法属性的命名规范介绍
- 女性最容易动心的21种时刻
- WSS(Windows Storage Server)2008R2使用指南(三)配置及使用篇
- vue打包放到Java项目里_【vue】webpack打包vue项目并且运行在Tomcat里面
- js正则表达式截取字符串中的数字(不包括正负号)
- C# 窗口大小及屏幕分辨率操作
- Atitit gc 垃圾回收原理与概论and 自动资源管理的艺术 v2 1. 为什么需要gc	1 1.1. 如果长期不被释放,可能导致OOM。	1 1.2. ,目的在于防止由程序猿引入的人为的内存
- java权限管理框架Shiro(最近学习整理)
- 4g 访问App 慢的原因
- Matlab 中simulink 打不开高版本问题解决方法
- 3D模型欣赏:汉服美女 【3D游戏建模教程】
- 梳理50道经典计算机网络面试题
- 计算机控制技术第二章,微型计算机控制技术 赖寿宏版 课件 第二章.ppt
- 什么是云服务和云服务端开发?
- “不限流量卡”真的不限量,但是却限制了这些!
- 盘盈的存货一般应作为什么处理