Spring多线程事务代码Demo

package com.scdq.env.aps.psm.service.test;

import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author zhangl
 * @date 2022-06-16 15:37
 */
@Service
public class TestServiceImpl {

    @Resource
    private PlatformTransactionManager transactionManager;

    public String test() {
        String result = "";
        CountDownLatch rollBackLatch = new CountDownLatch(1);
        CountDownLatch mainThreadLatch = new CountDownLatch(2);
        AtomicBoolean rollbackFlag = new AtomicBoolean(false);
        List<Future<String>> list = new ArrayList<>();
        // 线程有返回值
        Future<String> future = executor1(rollBackLatch, mainThreadLatch, rollbackFlag);
        list.add(future);
        // 线程无返回值
        executor2(rollBackLatch, mainThreadLatch, rollbackFlag);
        // 主线程业务执行完毕 如果其他线程也执行完毕 且没有报异常 正在阻塞状态中 唤醒其他线程 提交所有的事务
        // 如果其他线程或者主线程报错 则不会进入if 会触发回滚
        if (!rollbackFlag.get()) {
            try {
                mainThreadLatch.await();
                for (Future<String> f : list) {
                    if (!"success".equals(f.get())) {
                        result = f.get() + "。";
                    }
                }
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            } finally {
                rollBackLatch.countDown();
            }
        }
        return result;
    }

    public Future<String> executor1(CountDownLatch rollBackLatch, CountDownLatch mainThreadLatch,
                                    AtomicBoolean rollbackFlag) {
        ExecutorService executor = Executors.newCachedThreadPool();
        // result.get()阻塞线程
        return executor.submit(() -> {
            if (rollbackFlag.get()) {
                return "error"; // 如果其他线程已经报错 就停止线程
            }
            // 设置一个事务
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。
            TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
            try {
                // 业务处理开始
                // ..............
                // 业务处理结束
                rollBackLatch.await();// 线程等待
                if (rollbackFlag.get()) {
                    transactionManager.rollback(status);
                } else {
                    transactionManager.commit(status);
                }
                return "success";
            } catch (Exception e) {
                e.printStackTrace();
                // 如果出错了 就放开锁 让别的线程进入提交/回滚 本线程进行回滚
                rollbackFlag.set(true);
                rollBackLatch.countDown();
                mainThreadLatch.countDown();
                transactionManager.rollback(status);
                return "操作失败:" + e.getMessage();
            } finally {
                mainThreadLatch.countDown();
            }
        });
    }

    public void executor2(CountDownLatch rollBackLatch, CountDownLatch mainThreadLatch, AtomicBoolean rollbackFlag) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(() -> {
            if (rollbackFlag.get()) {
                return; // 如果其他线程已经报错 就停止线程
            }
            // 设置一个事务
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。
            TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
            try {
                // 业务处理开始
                // .....
                // 业务处理结束
                rollBackLatch.await();// 线程等待
                if (rollbackFlag.get()) {
                    transactionManager.rollback(status);
                } else {
                    transactionManager.commit(status);
                }
            } catch (Exception e) {
                e.printStackTrace();
                // 如果出错了 就放开锁 让别的线程进入提交/回滚 本线程进行回滚
                rollbackFlag.set(true);
                rollBackLatch.countDown();
                mainThreadLatch.countDown();
                transactionManager.rollback(status);
            } finally {
                mainThreadLatch.countDown();
            }
        });
    }

}

 

posted @ 2022-06-16 15:52  云翊宸  阅读(299)  评论(0编辑  收藏  举报