0
点赞
收藏
分享

微信扫一扫

线程池事务回滚

先看代码案例

@Transactional(rollbackFor = Exception.class)
    public boolean inStore(StoreLogReq req) {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.submit(() -> {
            List<StorageLog> list = new ArrayList<>();
            //增加入库记录
            for (material a :
                    req.getMaterial()) {
                StorageLog storageLog = new StorageLog();
                storageLog.setMaterialId(a.getMaterialId());
                list.add(storageLog);
            }
            mapper.insertBatch(list);
        });

        executor.submit(() -> {
         //根据货架和物料获取货位去亮灯
        //亮灯操作
            System.out.println("亮灯操作");
            throw new RuntimeException("入库失败----------------入库失败");
        });
        executor.shutdown();
        return false;
    }

其中抛出异常throw new RuntimeException("入库失败----------------入库失败");的确会导致事务回滚,但是代码中没有捕获这个异常,所以它会在子线程中抛出并终止线程。使用并没有实现真正的事务回滚,在使用线程池时,我们无法直接捕获子线程中的异常,因此需要使用Future来获取子线程的执行结果,并在主线程中处理异常情况。以下是修改后的代码示例:

@Transactional(rollbackFor = Exception.class)
public boolean inStore(StoreLogReq req) {
    ExecutorService executor = Executors.newFixedThreadPool(2);
    try {
        Future<?> future1 = executor.submit(() -> {
            // 增加入库记录
            // ...
            mapper.insertBatch(list);
        });

        Future<?> future2 = executor.submit(() -> {
            // 亮灯操作
            // ...
            throw new RuntimeException("入库失败----------------入库失败");
        });

        // 等待所有子线程执行完毕
        future1.get();
        future2.get();
    } catch (Exception e) {
        // 捕获子线程抛出的异常并处理
        e.printStackTrace();
        throw new RuntimeException("入库失败");
    } finally {
        executor.shutdown();
    }

    return false;
}

在修改后的代码中,我们使用Future对象来获取子线程的执行结果。通过future.get()方法来等待子线程执行完毕,如果子线程抛出异常,则在主线程中捕获并处理异常。

举报

相关推荐

0 条评论