实现一个交易系统,包括支付、订单、库存、物流等模块。

92 阅读2分钟

构建一个交易系统,涉及 支付、订单、库存、物流 等模块。以下是详细的 Java 设计方案,包含 架构选型、数据库设计、业务流程 以及 代码实现

  1. 系统架构

采用 Spring Boot + Spring Cloud + MySQL + Redis + RabbitMQ + Seata(分布式事务)

1.1 技术选型

  1. 核心业务流程

① 用户下单

• 创建订单

• 扣减库存

• 冻结资金(支付)

• 通知物流发货

② 订单支付

• 扣款成功 → 订单状态变更 → 通知物流

• 扣款失败 → 释放库存 → 取消订单

③ 订单取消

• 订单超时未支付,自动取消

• 释放库存,解冻资金

  1. 数据库设计

订单表(t_order)

CREATE TABLE t_order (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    product_id BIGINT NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    status VARCHAR(20) NOT NULL DEFAULT 'CREATED',
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

库存表(t_stock)

CREATE TABLE t_stock (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    product_id BIGINT NOT NULL,
    total INT NOT NULL,
    available INT NOT NULL
);

支付表(t_payment)

CREATE TABLE t_payment (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    order_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

4. #### 代码实现

4.1 订单微服务

订单Service

@Service
public class OrderService {
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private StockClient stockClient;
    @Autowired
    private PaymentClient paymentClient;
    @Autowired
    private MessageSender messageSender;

    @GlobalTransactional // Seata 全局事务
    public Order createOrder(Long userId, Long productId, BigDecimal amount) {
        // 1. 扣减库存
        stockClient.deductStock(productId, 1);
        
        // 2. 创建订单
        Order order = new Order(userId, productId, amount, "CREATED");
        orderRepository.save(order);
        
        // 3. 预扣资金
        paymentClient.freezeAmount(userId, amount);

        // 4. 发送订单创建成功的消息
        messageSender.send("order_created", order.getId());
        
        return order;
    }
}

订单控制器

@RestController
@RequestMapping("/orders")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @PostMapping("/create")
    public ResponseEntity<?> createOrder(@RequestBody OrderRequest request) {
        Order order = orderService.createOrder(request.getUserId(), request.getProductId(), request.getAmount());
        return ResponseEntity.ok(order);
    }
}

4.2 库存微服务

库存Service

@Service
public class StockService {
    @Autowired
    private StockRepository stockRepository;

    @Transactional
    public void deductStock(Long productId, int count) {
        Stock stock = stockRepository.findByProductId(productId);
        if (stock.getAvailable() < count) {
            throw new RuntimeException("库存不足");
        }
        stock.setAvailable(stock.getAvailable() - count);
        stockRepository.save(stock);
    }
}

库存Controller

@RestController
@RequestMapping("/stock")
public class StockController {
    @Autowired
    private StockService stockService;

    @PostMapping("/deduct")
    public ResponseEntity<?> deductStock(@RequestParam Long productId, @RequestParam int count) {
        stockService.deductStock(productId, count);
        return ResponseEntity.ok("库存扣减成功");
    }
}

4.3 支付微服务

支付Service

@Service
public class PaymentService {
    @Autowired
    private PaymentRepository paymentRepository;

    @Transactional
    public void freezeAmount(Long userId, BigDecimal amount) {
        Payment payment = new Payment(userId, amount, "FROZEN");
        paymentRepository.save(payment);
    }

    @Transactional
    public void confirmPayment(Long paymentId) {
        Payment payment = paymentRepository.findById(paymentId).orElseThrow();
        payment.setStatus("COMPLETED");
        paymentRepository.save(payment);
    }
}

支付Controller

@RestController
@RequestMapping("/payment")
public class PaymentController {
    @Autowired
    private PaymentService paymentService;

    @PostMapping("/freeze")
    public ResponseEntity<?> freezeAmount(@RequestParam Long userId, @RequestParam BigDecimal amount) {
        paymentService.freezeAmount(userId, amount);
        return ResponseEntity.ok("资金冻结成功");
    }
}

4.4 物流微服务

物流Service

@Service
public class LogisticsService {
    @Autowired
    private LogisticsRepository logisticsRepository;

    @Transactional
    public void shipOrder(Long orderId) {
        Logistics logistics = new Logistics(orderId, "SHIPPED");
        logisticsRepository.save(logistics);
    }
}

物流消息消费

@RabbitListener(queues = "order_created")
public void handleOrderCreated(Long orderId) {
    shipOrder(orderId);
}
  1. 分布式事务方案

采用 Seata TCC 模式 确保事务一致性:

  1. Try: 扣减库存、冻结支付

  2. Confirm: 扣款成功,发货

  3. Cancel: 释放库存,解冻支付

  4. 总结

Spring Cloud 架构,微服务解耦

Seata 分布式事务,确保一致性

RabbitMQ 异步处理,提升并发能力

Redis 缓存,优化读性能