MST
星途 面试题库

面试题:Java中thenRunAsync方法在复杂业务场景中的优化与设计

假设你正在开发一个电商系统,在用户下单后,需要进行库存扣减、订单记录保存等操作,完成这些操作后,要异步执行一个生成订单报表的任务(使用thenRunAsync方法)。考虑到系统的高并发和性能优化,你将如何设计这一流程?请详细描述实现思路,并给出关键代码片段,同时说明如何处理可能出现的各种异常情况。
36.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 事务管理:使用数据库事务来确保库存扣减和订单记录保存的原子性,要么都成功,要么都失败。
  2. 异步任务:使用线程池来管理异步任务,在库存扣减和订单记录保存成功后,提交生成订单报表的任务到线程池执行。
  3. 异常处理:在事务内捕获异常进行回滚,异步任务中捕获异常进行日志记录和必要的错误处理。

关键代码片段(以Java为例,假设使用Spring框架和MySQL数据库)

  1. 配置线程池
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration
public class ThreadPoolConfig {

    @Bean
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(100);
        executor.setQueueCapacity(200);
        executor.initialize();
        return executor;
    }
}
  1. 订单处理服务
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.Future;

@Service
public class OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);

    @Autowired
    private InventoryService inventoryService;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private OrderReportService orderReportService;

    @Transactional
    public Future<String> processOrder(Order order) {
        try {
            // 库存扣减
            boolean inventorySuccess = inventoryService.decreaseInventory(order.getProductId(), order.getQuantity());
            if (!inventorySuccess) {
                throw new RuntimeException("库存不足");
            }
            // 订单记录保存
            orderRepository.save(order);
            // 异步执行生成订单报表任务
            return asyncGenerateOrderReport(order.getOrderId());
        } catch (Exception e) {
            // 事务内异常回滚
            logger.error("订单处理失败", e);
            throw new RuntimeException("订单处理失败", e);
        }
    }

    @Async("asyncExecutor")
    public Future<String> asyncGenerateOrderReport(Long orderId) {
        try {
            orderReportService.generateReport(orderId);
            return new AsyncResult<>("订单报表生成成功");
        } catch (Exception e) {
            // 异步任务异常处理
            logger.error("订单报表生成失败", e);
            return new AsyncResult<>("订单报表生成失败");
        }
    }
}
  1. 库存服务和订单仓储接口示例
public interface InventoryService {
    boolean decreaseInventory(Long productId, int quantity);
}

public interface OrderRepository {
    void save(Order order);
}
  1. 订单报表服务接口示例
public interface OrderReportService {
    void generateReport(Long orderId);
}

异常处理

  1. 事务内异常:在processOrder方法中,捕获到异常后进行日志记录并抛出,Spring的事务管理机制会自动回滚库存扣减和订单记录保存的操作。
  2. 异步任务异常:在asyncGenerateOrderReport方法中,捕获异常并进行日志记录,返回一个包含错误信息的Future对象,方便调用者了解任务执行结果。同时可以根据实际业务需求,进行重试等操作。