CompletableFuture 多线程事务

码示例代码示例

@Resource
private PlatformTransactionManager transactionManager;
    @Transactional(rollbackFor = Exception.class)
    public String uploadBodyFatScaleData(Long patientUserId, AppBodyFatAddReqVO createReqVO) {
        // 插入
        BodyFatDO bodyFat = BodyFatConvert.INSTANCE.convert(createReqVO);
        //设置患者id
        PatientUserDO patient = patientUserService.getPatient(patientUserId);
        String patientId = patient.getPatientId();
        bodyFat.setPatientId(patientId);
        bodyFatMapper.insert(bodyFat);

        //使用一个线程池执行异步任务
        ThreadPoolExecutor executor = ExecutorBuilder.create()
            .setCorePoolSize(FIVE_INTEGER)
            .setMaxPoolSize(TEN_INTEGER)
            .build();

        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);

        //更新患者最后活动时间
        CompletableFuture<Void> updateLastActiveTimeTask = CompletableFuture.runAsync(() -> {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(@NonNull TransactionStatus status) {
                    patientUserService.updateTheLastActiveTime(patientUserId);
                }
            });
        }, executor);

        //更新患者初始体重和现在体重
        double weight = createReqVO.getWeight();
        double patientUserMinWeight = patient.getMinWeight();
        double patientUserMaxWeight = patient.getMaxWeight();
        Long numberOfWeighing = getNumberOfWeighingByPatientId(patientId);
        CompletableFuture<Void> updateWeightTask = CompletableFuture.runAsync(() -> {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(@NonNull TransactionStatus status) {
                    patientUserService.updatePatientInitialAndCurrentAndMinAndMaxWeight(
                        patientUserId, weight,
                        //patientUserMinWeight小于等于当前体重的话就拿现在体重
                        Math.min(Math.min(patientUserMinWeight, weight), weight),
                        Math.max(patientUserMaxWeight, weight),
                        getFirstWeighing(patientId),
                        numberOfWeighing);
                }
            });
        }, executor);

        // 新增历史记录
        CompletableFuture<Void> addHistoryTask = CompletableFuture.runAsync(() -> {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(@NonNull TransactionStatus status) {
                    AddHistoryUtil.addHistory(EventRecordEnums.WEIGHT, patient.getId(),
                        String.valueOf(createReqVO.getWeight()),
                        RecordTypeEnum.WEIGHT.getValue(),
                        createReqVO.getMeasuringTime());
                }
            });
        }, executor);

        //等待所有任务完成后返回结果
        return CompletableFuture.allOf(updateLastActiveTimeTask, updateWeightTask, addHistoryTask)
            .thenApply(v -> bodyFat.getId())
            .join();
 
    }

在这段代码中,@Transactional 注解用于管理 uploadBodyFatScaleData 方法的事务。但是,使用 CompletableFuture.runAsync 与自定义的 ThreadPoolExecutor 异步执行任务意味着这些任务在原始事务的范围之外执行。

相反,创建了一个新的 TransactionTemplate 并用于在它们自己的事务中执行这些任务。这意味着每个任务都在其自己的事务中执行,独立于由 @Transactional 注解管理的原始事务。

因此,在这段代码中,异步任务的事务将按预期工作,但它们将与由 @Transactional 注解管理的原始事务分开。

TransactionTemplate 是 如何工作的?

TransactionTemplate 是一个模板类,它简化了编程式事务划分和事务异常处理。它的核心方法是 execute,它支持实现 TransactionCallback 接口的事务代码。此模板处理事务生命周期和可能的异常,因此无需显式处理事务,既不需要 TransactionCallback 实现,也不需要调用代码 ¹。

要使用它,我们应该首先使用 PlatformTransactionManager 对其进行初始化。我们可以使用依赖注入来设置此模板 ¹。

例如:

@Autowired
private PlatformTransactionManager transactionManager;
private TransactionTemplate transactionTemplate;

@BeforeEach
void setUp() {
    transactionTemplate = new TransactionTemplate(transactionManager);
}

(3) 深入理解TransactionTemplate编程式事务 - CSDN博客. https://blog.csdn.net/qq_33404395/article/details/83377382.

posted @ 2023-07-12 09:52  别有风景  阅读(1124)  评论(0)    收藏  举报