1. 事故现场还原:支付成功但订单消失的诡异现象
上周五下午3点,我们的支付系统突然爆发大规模异常。用户反馈支付成功后订单列表却显示空白,更诡异的是部分用户尝试修改订单时系统提示"获取锁超时"。作为值班开发,我第一时间查看了数据库监控,发现有几个事务已经持续了2个多小时没有提交,锁住了订单表的关键行。
通过分析线程堆栈,我们定位到这些挂起的事务都来自同一个业务服务。但奇怪的是,该服务的日志显示所有操作都正常完成,甚至打印了"事务提交成功"的记录。最让人困惑的是,这个问题并非100%复现——大约70%的请求会失败,但剩下的30%却能正常完成订单创建。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 应急处理与问题定位
2.1 紧急恢复措施
面对线上事故,我们立即执行了标准应急流程:
- 首先通过Kill命令终止了长时间运行的事务
- 对受影响用户进行补偿处理
- 紧急重启了相关服务实例
重启后系统暂时恢复正常,但这只是治标不治本。我们需要找到根本原因,防止问题再次发生。
2.2 代码审查发现问题
对比最近一周的代码变更,我们发现新上线的优惠券核销服务中存在可疑代码片段:
java复制@Service
public class CouponService {
@Autowired
private SqlSession sqlSession;
public void redeemCoupon(Long userId, Long couponId) {
// 手动开启事务
sqlSession.getConnection().setAutoCommit(false);
// 核销优惠券
couponMapper.updateStatus(couponId, "USED");
// 特殊条件判断
if (isSpecialUser(userId)) {
// 这里直接return导致事务泄漏!
return;
}
// 正常提交
sqlSession.commit();
}
}
