多个线程下处理事务

 

springboot项目都是声明式事务,在多个线程事务处理时,需要我们使用手动事务管理器

    @Resource
    private PlatformTransactionManager platformTransactionManager;
    @Resource
    private TransactionTemplate transactionTemplate;

这是是两个及以上线程协作,需要借助线程安全的工具,这里使用CountDownLatch处理线程间同步,使用CopyOnWriteArraySet 保存子线程运行的结果,然后由主线程决策子线程是否提交

 

     ExecutorService executor = Executors.newSingleThreadExecutor();
        CountDownLatch monitorLatch = new CountDownLatch(1);
        CountDownLatch subLatch = new CountDownLatch(1);
        CopyOnWriteArraySet<Boolean> resultSet = new CopyOnWriteArraySet<>();

        AtomicBoolean isSuc = new AtomicBoolean(false);

        executor.submit(()->{
            TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionTemplate);
            try{
                log.info("----------begin:开始操作-------");
                boolean update = marketBankBusinessTransService.lambdaUpdate().set(MarketBankBusinessTrans::getVerificationState, 0)
                        .eq(MarketBankBusinessTrans::getId, "1619265921141579778")
                        .update();

                resultSet.add(update);
                subLatch.countDown();

                monitorLatch.await();

                if(BooleanUtil.isFalse(isSuc.get())){
                    throw new RuntimeException("主线程决策为回滚---");
                }
                platformTransactionManager.commit(transactionStatus);
            } catch (Exception e){
                e.printStackTrace();
                subLatch.countDown();
                platformTransactionManager.rollback(transactionStatus);
            }
        });


        try {
            log.info("----------begin:开始操作-------");
            marketBankBusinessTransService.lambdaUpdate().set(MarketBankBusinessTrans::getVerificationState, 1)
                    .eq(MarketBankBusinessTrans::getId, "1619266976181047297")
                    .update();

            subLatch.await();
            if(resultSet.contains(true)){
                isSuc.set(true);
            }else {
                throw new RuntimeException("子线程执行错误,抛出异常,让主线程回滚");
            }
        } catch (Exception e){
            isSuc.set(false);
            throw new RuntimeException("主线程执行错误");
        } finally {
            monitorLatch.countDown();
        }

 

posted @ 2023-01-30 17:09  小小小小青石  阅读(231)  评论(0)    收藏  举报