第4章 高并发与账务一致性
支付系统在秒杀、批量扣款等高并发场景下,既要保证账户余额不超扣,又要防止重复扣款。核心解法围绕乐观锁、分布式锁、幂等设计展开,同时依赖异步对账兜底最终一致性。面试中通常会从具体业务场景切入,层层追问边界与取舍。
高频面试问答卡片
🎯 问题1:如何设计高并发下的并发扣款,保证账户余额不超扣?
| 面试官考察点 | 是否理解原子操作、乐观锁与分布式锁的适用边界,能否考虑并发、重试与对账的整体方案 |
| 回答框架 | ① 使用乐观锁(UPDATE account SET balance=balance-amount WHERE id=? AND balance>=amount)② 配合重试机制(更新行数为0则回滚并重试) ③ 对极端冲突场景引入分布式锁(Redis锁+超时续期) ④ 异步对账兜底,保障最终一致 |
| 简短示例回答 | 一般采用乐观锁,在SQL中利用余额判据原子扣款。若更新行数为0则说明余额不足或并发冲突,业务方重试。对于热点账户,可前置分布式锁减少重试开销,同时设置锁超时和续期,最后通过每日对账发现并修正不一致。 |
| 可能追问 | 乐观锁在极高并发下性能如何?如何避免ABA?分布式锁死锁如何解决?锁超时时间怎么设? |
| 避坑提醒 | ❌ 不要将余额检查放在应用层(非原子操作) ✅ 必须利用数据库或Redis原子指令 ⚠️ 分布式锁注意锁续期,防止业务未完成锁自动释放 |
🎯 问题2:如何设计幂等接口,防止重复扣款?
| 面试官考察点 | 幂等方案设计能力、唯一ID生成策略、去重表与缓存的配合、补偿机制 |
| 回答框架 | ① 请求方生成全局唯一幂等键(UUID/雪花ID) ② 服务端先查Redis幂等表,存在则直接返回历史结果 ③ 不存在则执行扣款,并写入DB唯一索引幂等表(与业务事务同库或可靠消息) ④ 超时情况做状态机查询,配合定时清理过期记录 |
| 简短示例回答 | 每次扣款携带全局唯一ID,服务端先检查Redis,若命中则直接返回;否则执行扣款事务,同时向幂等表中插入该ID(利用数据库唯一索引防并发),事务成功则写入Redis。超时或失败时客户端重试,服务端返回已有结果。 |
| 可能追问 | 幂等表如何清理?分布式场景下幂等键生成策略?补偿(冲正)与幂等关系?如何保证幂等检查与业务操作原子性? |
| 避坑提醒 | ❌ 幂等键由服务端生成(客户端无法保证重传时唯一) ✅ 必须由客户端提交并携带 ⚠️ 避免用业务订单号直接作为幂等键(可能被伪造或重复提交) |
🎯 问题3:对比乐观锁、悲观锁、分布式锁在账务场景的适用场景?
| 面试官考察点 | 对三种锁原理与性能的深入理解,能否根据并发量、失败代价做出合理选型 |
| 回答框架 | ① 乐观锁:适合低冲突、短事务场景(常见账户扣款),利用version或余额判据,重试成本低 ② 悲观锁(SELECT FOR UPDATE):适合高冲突、长事务(对账批次、红包拆分),死锁风险需关注 ③ 分布式锁(Redis/zk):适合跨服务、跨库操作同一资源,注意锁超时、脑裂、性能开销 |
| 简短示例回答 | 乐观锁适用于普通扣款,使用version字段,冲突少时性能极高。悲观锁用于对账批次等长操作,防止其他事务修改。分布式锁用于跨服务操作同一账户(如组合支付),搭配Redlock解决脑裂,但需容忍性能损失。选型核心看冲突概率与失败重试代价。 |
| 可能追问 | 乐观锁一定比悲观锁好吗?分布式锁如何降级?同时使用乐观锁与分布式锁是否矛盾? |
| 避坑提醒 | ❌ 不要一刀切认为乐观锁最优(热点账户冲突高时重试压垮DB) ✅ 热点账户推荐排队串行化+分布式锁 ⚠️ 悲观锁长事务可能导致锁超时或死锁,需设置超时时间 |
公司侧重点
- 蚂蚁集团:强一致性,倾向TCC + 分布式锁,对账要求分钟级,不允许任何超扣
- 腾讯支付:偏最终一致性,MQ + 乐观锁为主,容忍短暂不一致,每日对账发现并冲正
- 字节跳动:追求高吞吐,热点账户使用本地乐观锁 + 异步补偿,非热点用乐观锁
- 美团/京东:混合策略,关键链路(如钱包扣款)用分布式锁+版本号,普通业务用乐观锁
面试官画像
- 背景:5年以上支付/交易架构经验,多为P7+级别,曾在公司设计过高并发账务核心
- 关注点:不会只看方案名称,会深入追问——版本号与余额判据选哪个?锁超时设置依据?对账延迟容忍度?
- 考察风格:从简单扣款开始,逐步增加热点、跨库、降级等复杂条件,观察你是否能灵活组合方案
- 加分项:主动提出数据对账、监控报警、兜底补偿机制,能用实际压测数据说明(如乐观锁在TPS 5000时冲突率X%)
整体回答框架总结
| 阶段 | 关键动作 | 对应知识点 |
|---|---|---|
| 1. 识别问题 | 明确是否是热点账户、跨服务、允许最终一致还是强一致 | 场景分析能力 |
| 2. 方案选型 | 根据冲突率选择乐观锁/分布式锁/排队串行化 | 锁原理 & 性能对比 |
| 3. 幂等兜底 | 设计幂等键与去重表,防止重复扣款 | 幂等设计要素 |
| 4. 异常处理 | 重试策略、锁超时续期、死锁回滚 | 容错与降级 |
| 5. 对账监控 | 每日/实时对账,发现不一致后补偿或告警 | 最终一致性闭环 |
💡 面试策略:回答时先抛出核心方案(如乐观锁+幂等+对账),再根据面试官追问深入细节。准备一个自己亲身参与或设计的扣款系统案例(例如“某支付平台秒杀活动,日扣款500万笔”),用STAR结构描述冲突率、锁超时、对账延迟等真实指标,会极大加分。