【业务逻辑实战】用 Java 和 MySQL 模拟「电商订单流转系统」
·

需求分析
电商订单流转系统核心功能包括:用户下单、支付处理、库存扣减、物流跟踪和状态更新。涉及订单表、商品表、用户表、库存表等数据模型,需实现事务一致性。
数据库设计
-- 用户表
CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`balance` decimal(10,2) DEFAULT '0.00',
PRIMARY KEY (`id`)
);
-- 商品表
CREATE TABLE `product` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`price` decimal(10,2) NOT NULL,
PRIMARY KEY (`id`)
);
-- 库存表
CREATE TABLE `inventory` (
`product_id` bigint NOT NULL,
`stock` int NOT NULL DEFAULT '0',
PRIMARY KEY (`product_id`)
);
-- 订单表
CREATE TABLE `order` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL,
`total_amount` decimal(10,2) NOT NULL,
`status` varchar(20) NOT NULL DEFAULT 'CREATED',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
);
-- 订单明细表
CREATE TABLE `order_item` (
`id` bigint NOT NULL AUTO_INCREMENT,
`order_id` bigint NOT NULL,
`product_id` bigint NOT NULL,
`quantity` int NOT NULL,
`price` decimal(10,2) NOT NULL,
PRIMARY KEY (`id`)
);
Java 核心实现
使用 Spring Boot + MyBatis 框架实现:
// 订单服务层
@Service
@Transactional
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private InventoryMapper inventoryMapper;
@Autowired
private UserMapper userMapper;
public OrderDTO createOrder(OrderCreateRequest request) {
// 校验库存
request.getItems().forEach(item -> {
Inventory inventory = inventoryMapper.selectById(item.getProductId());
if (inventory.getStock() < item.getQuantity()) {
throw new BusinessException("库存不足");
}
});
// 扣减库存
request.getItems().forEach(item -> {
inventoryMapper.deductStock(item.getProductId(), item.getQuantity());
});
// 创建订单
Order order = new Order();
order.setUserId(request.getUserId());
order.setTotalAmount(calculateTotal(request.getItems()));
orderMapper.insert(order);
// 创建订单明细
request.getItems().forEach(item -> {
OrderItem orderItem = new OrderItem();
orderItem.setOrderId(order.getId());
orderItem.setProductId(item.getProductId());
orderItem.setQuantity(item.getQuantity());
orderItem.setPrice(getProductPrice(item.getProductId()));
orderItemMapper.insert(orderItem);
});
return convertToDTO(order);
}
public void payOrder(Long orderId) {
Order order = orderMapper.selectById(orderId);
User user = userMapper.selectById(order.getUserId());
if (user.getBalance().compareTo(order.getTotalAmount()) < 0) {
throw new BusinessException("余额不足");
}
userMapper.deductBalance(order.getUserId(), order.getTotalAmount());
orderMapper.updateStatus(orderId, "PAID");
}
}
状态机设计
订单状态流转建议采用状态模式:
public interface OrderState {
void pay(Order order);
void deliver(Order order);
void receive(Order order);
}
public class CreatedState implements OrderState {
public void pay(Order order) {
// 支付逻辑
order.setState(new PaidState());
}
// 其他方法实现...
}
事务处理要点
- 库存扣减与订单创建需在同一事务
- 支付操作需要保证余额扣减和订单状态更新的原子性
- 建议使用@Transactional注解管理事务边界
性能优化建议
- 库存扣减使用乐观锁:
UPDATE inventory SET stock = stock - #{quantity}
WHERE product_id = #{productId} AND stock >= #{quantity}
- 订单查询分库分表策略
- 热点商品库存采用预扣减+异步同步机制
异常处理方案
- 库存不足时触发补偿事务
- 支付失败时回滚订单状态
- 分布式场景考虑引入Saga模式
扩展性设计
- 订单状态变更通过事件驱动架构通知其他系统
- 物流模块可单独微服务化
- 支付模块支持多支付渠道插件式扩展
更多推荐


所有评论(0)