多线程实战

想要达成的效果

1、保存订单

2、扣减库存

要求两个操作在同一个方法里面,保存订单使用分布式事务,扣减库存使用使用本地事务,扣减库存失败不会影响保存订单方法,使用多线程完成。

方式一:分布式事务+本地手动事务

适用于调同类的其他方法。

使用Runnable方式演示:

    @Override
    @Transactional
    public int submit(Book book) {
        int userId = 100;
        String orderId = System.currentTimeMillis() + "" + userId;
        Order order = new Order(orderId, new Date(), new BigDecimal("99.9"), 0, userId);
        // 保存订单
        int result = orderDao.saveOrder(order);
        // int a = 10 / 0;
        if (result == 1) {
            new Thread(() -> {
                TransactionStatus status = transactionManager.getTransaction(
                        new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW));
                try {
                    reduceStock(book.getId());
                    transactionManager.commit(status);
                } catch (Exception e) {
                    transactionManager.rollback(status);
                    throw new RuntimeException(e);
                }
            }).start();
        }
        
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        
        // if ("Y".equals(submitSwitch)) {
        //     throw new RuntimeException("回滚,用于对比。userId: " + userId);
        // }
        return result;
    }
    
    // @Transactional // 同类中的方法调用失效
    public void reduceStock(int id) {
        bookDao.reduceStock(id);
        int a = 10 / 0;
    }

方式二:分布式事务+@Transactional本地事务

适用于调不同类的方法。

使用CompletableFuture方式演示:

    @Override
    @Transactional
    public int submit(Book book) {
        int userId = 100;
        String orderId = System.currentTimeMillis() + "" + userId;
        Order order = new Order(orderId, new Date(), new BigDecimal("99.9"), 0, userId);
        // 1.保存订单
        int result = orderDao.saveOrder(order);
        // int a = 10 / 0;
        if (result == 1) {
            // 2. 异步执行库存扣减(独立本地事务)
            CompletableFuture.runAsync(() -> {
                try {
                    bookService.reduceStock(book.getId());
                } catch (Exception e) {
                    // 记录日志或进行补偿操作
                    System.err.println("[Inventory Failed] "+e.getMessage());
                }
            }); 
            
        }
        
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        
        // if ("Y".equals(submitSwitch)) {
        //     throw new RuntimeException("回滚,用于对比。userId: " + userId);
        // }
        return result;
    }

使用@Async方式演示:需要配置Spring的Async相关配置

    @Override
    @Transactional
    public int submit(Book book) {
        int userId = 100;
        String orderId = System.currentTimeMillis() + "" + userId;
        Order order = new Order(orderId, new Date(), new BigDecimal("99.9"), 0, userId);
        // 保存订单
        int result = orderDao.saveOrder(order);
        // int a = 10 / 0;
        if (result == 1) {
            // 2. 异步执行库存扣减(独立本地事务)
            bookService.reduceStock(book.getId()); // 使用 @Async
        }
        
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        
        // if ("Y".equals(submitSwitch)) {
        //     throw new RuntimeException("回滚,用于对比。userId: " + userId);
        // }
        return result;
    }
    @Override
    // 独立本地事务(传播级别:REQUIRES_NEW)
    @Transactional(
            propagation = Propagation.REQUIRES_NEW,
            rollbackFor = Exception.class
    )
    @Async("inventoryThreadPool")  // 使用独立线程池
    public void reduceStock(Integer id) {
        bookDao.reduceStock(id);
        int a = 10 / 0;
    }
/**
 * @Description: 线程池配置类
 */
@Configuration
@EnableAsync
public class ThreadPoolConfig {
    
    @Bean("inventoryThreadPool")
    public Executor inventoryThreadPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("inventory-thread-");
        executor.initialize();
        return executor;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值