异步编排多线程任务事务控制

/**
 * <p>
 * <B>Description: 异步编排多线程任务事务控制</B>
 * </P>
 * Revision Trail: (Date/Author/Description)
 * 2022/12/26 Ryan Huang CREATE
 * 多线程异步处理时的事务管理
 *      1. addFunction 添加要异步执行的方法
 *      2. execute 方法中使用全局的计数器和异常标记字段统计异步线程执行的结果,当所有的异步线程执行完后根据异常标记字段判断是否回滚还是提交事务。
 * @author Ryan Huang
 * @version 1.0
 */
public class ThreadTransaction {

    /**
     * 日志
     */
    private final Logger LOG = LoggerFactory.getLogger(ThreadTransaction.class);

    /**
     * 事务管理
     */
    private PlatformTransactionManager platformTransactionManager;

    /**
     * JUC线程池
     */
    private ThreadPoolExecutor threadPoolExecutor;

    /**
     * Spring线程池
     */
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;


    private List<Supplier> supplierList = new ArrayList<>();

    /**
     * 执行计数器
     */
    private volatile CountDownLatch countDownLatch;

    /**
     * 是否存在异常
     */
    AtomicReference<Boolean> isError = new AtomicReference<>(false);

    public ThreadTransaction(PlatformTransactionManager platformTransactionManager, ThreadPoolTaskExecutor threadPoolTaskExecutor) {
        this.platformTransactionManager = platformTransactionManager;
        this.threadPoolTaskExecutor = threadPoolTaskExecutor;
    }

    public ThreadTransaction(PlatformTransactionManager platformTransactionManager, ThreadPoolExecutor threadPoolExecutor) {
        this.platformTransactionManager = platformTransactionManager;
        this.threadPoolExecutor = threadPoolExecutor;
    }

    public ThreadTransaction(PlatformTransactionManager platformTransactionManager, ThreadPoolTaskExecutor threadPoolTaskExecutor, int size){
        this.platformTransactionManager = platformTransactionManager;
        this.threadPoolTaskExecutor = threadPoolTaskExecutor;
        supplierList = new ArrayList<>(size);
    }

    /**
     * 添加要异步执行的方法程序
     */
    public boolean addFunction(Supplier supplier){
        return supplierList.add(supplier);
    }

    public void execute(){
        LOG.info("多线程事务开始...");
        countDownLatch = new CountDownLatch(supplierList.size());
        for (Supplier supplier : supplierList) {
            this.threadPoolTaskExecutor.submit(new TransactionRunnable(platformTransactionManager, supplier));
        }
        try {
            if (isError.get()) {
                LOG.error("多线程执行失败,事务已回滚!");
                throw new RuntimeException("多线程执行失败!");
            }
            LOG.info("多线程执行成功,事务已提交!");
        }catch (Exception e){
            LOG.error("多线程执行失败:" + e.getMessage());
            e.printStackTrace();
        }
    }

    class TransactionRunnable implements Runnable{

        /**
         * 事务管理
         */
        private PlatformTransactionManager platformTransactionManager;

        private Supplier supplier;

        public TransactionRunnable(PlatformTransactionManager platformTransactionManager, Supplier supplier) {
            this.platformTransactionManager = platformTransactionManager;
            this.supplier = supplier;
        }

        @Override
        public void run() {
            DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
            defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            TransactionStatus transaction = this.platformTransactionManager.getTransaction(defaultTransactionDefinition);
            try {
                this.supplier.get();
            } catch (Exception e){
                isError.set(true);
                LOG.error("多线程事务执行失败{}", e.getMessage());
                e.printStackTrace();
            }
            countDownLatch.countDown();
            try {
                if (isError.get()) {
                    LOG.info("多线程事务(子线程)回滚");
                    platformTransactionManager.rollback(transaction);
                } else {
                    LOG.info("多线程事务(子线程)提交");
                    platformTransactionManager.commit(transaction);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

posted @   IamHzc  阅读(502)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
历史上的今天:
2020-12-27 JAVA setObject使用
点击右上角即可分享
微信分享提示
主题色彩