1. 业务逻辑冲突的本质:比线程同步更隐蔽的战场
当我们在讨论并发问题时,线程安全总是第一个被提起的话题。锁、原子操作、内存屏障这些概念早已深入人心。但真实业务场景中,有一种更隐蔽的并发问题——业务逻辑冲突,它不会导致程序崩溃,却会让系统状态陷入混乱。
上周我就遇到一个典型案例:电商平台的优惠券系统。两个用户同时领取最后一张满减券,系统检查库存都显示"剩余1张",结果两人都领取成功,导致超发。这不是简单的线程安全问题——数据库事务隔离级别已经是SERIALIZABLE,代码里也加了同步锁。问题出在业务逻辑的设计缺陷:检查库存和扣减库存被拆分成两个独立操作,中间存在时间差。
这种业务层面的并发冲突有三大特征:
- 不会抛出异常,系统看似正常运行
- 往往涉及多个业务实体间的状态联动
- 只能在特定业务场景下复现
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 传统解决方案的局限性:从锁到状态机
2.1 为什么synchronized不够用
Java的synchronized关键字可以保证方法级别的原子性,但面对跨服务的业务操作就力不从心。比如订单支付场景:
java复制// 典型的问题代码结构
public void payOrder(Long orderId) {
Order order = orderService.getById(orderId);
if(order.getStatus() == UNPAID) {
boolean success = paymentService.pay(order);
if(success) {
order.setStatus(PAID); // 这里可能被并发覆盖
orderService.update(order);
}
}
}
即使给整个方法加锁,如果paymentService是远程调用,锁根本覆盖不到其他服务的操作。更不用说分布式环境下本地锁完全失效的情况。
2.2 状态机的救赎与局限
状态机模式是解决业务冲突的常见方案。通过明确定义状态转换规则,可以避免非法状态迁移:
mermaid复制stateDiagram-v2
[*] --> UNPAID
UNPAI
