面试官与谢飞机的三轮灵魂拷问:从Spring Boot启动到分布式事务

📅 2026/7/9 3:33:43 👁️ 阅读次数 📝 编程学习
面试官与谢飞机的三轮灵魂拷问:从Spring Boot启动到分布式事务

面试官与谢飞机的三轮灵魂拷问:从Spring Boot启动到分布式事务

“谢飞机,你简历写‘精通Spring Boot’,那我问你——它到底怎么‘启动’的?”
—— 面试官推了推眼镜,咖啡杯还没放下。
谢飞机咽了口唾沫:“呃…main方法里run一个SpringApplication?”

🔁 第一轮:Spring Boot 启动不是魔法,是约定大于配置

SpringApplication.run() 表面简单,背后是三层自动装配引擎:

  1. SpringFactoriesLoader 扫描 META-INF/spring.factories,加载所有 ApplicationContextInitializerApplicationRunner
  2. @EnableAutoConfiguration 触发 AutoConfigurationImportSelector,按 spring-boot-autoconfigure 中的 xxxAutoConfiguration 类条件注入 Bean;
  3. ConditionOnClass / ConditionOnMissingBean 确保“有XX类才配XXBean,没XXBean才创建默认Bean”。

✅ 关键认知:自动配置 = 条件化Bean注册 + starter依赖驱动,不是黑箱。

// 示例:DataSourceAutoConfiguration 的核心判断
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(DataSource.class)
public class DataSourceAutoConfiguration { ... }

🧱 第二轮:库存扣减,为什么不能只用 decrby

电商秒杀中,“扣100件库存”看似一行命令:

DECRBY stock:1001 100

但问题来了:

  • ❌ 若超卖(如并发1000请求,库存只剩50),DECRBY 不校验下限 → 库存变负数;
  • ❌ 若需“扣库存+写订单”原子性,单靠Redis无法跨系统保证。

💡 正解:Lua脚本 + 粒度锁优化

  • Lua脚本在Redis服务端原子执行校验+扣减;
  • 锁粒度 ≠ 商品ID,而是 order:{orderId}:item:{itemId} → 避免同一商品被不同订单阻塞。
-- lua_stock_deduct.lua
local stockKey = KEYS[1]
local required = tonumber(ARGV[1])
local current = tonumber(redis.call('GET', stockKey))
if current >= required thenredis.call('DECRBY', stockKey, required)return 1
elsereturn 0 -- 失败
end

🌐 第三轮:下单成功,但积分没发、短信没发?最终一致性怎么兜底?

理想链路:
下单事务扣库存(Redis)发积分(RabbitMQ)发短信(RabbitMQ)

但网络抖动、服务宕机怎么办?
❌ 两阶段提交(2PC)性能差、XA协议难落地;
✅ 推荐:本地事务表 + Saga 模式

步骤 操作 补偿动作
T1 写订单 + 本地事务表(status=processing) 删除订单 + 更新status=compensated
T2 扣库存(Redis Lua) Lua回滚:INCRBY
T3 发送积分消息(RabbitMQ, persistent=true) 无(幂等消费)
T4 发送短信消息 无(幂等消费)

📌 Saga 核心思想:每个步骤都可逆,失败时反向执行补偿事务(而非阻塞等待)。

💡 技术点详解(给刚入门的你)

问题 为什么这么设计? 小白一句话
Q:为啥不用 @Transactional 包住全部? 因为Redis、RabbitMQ不在JDBC事务范围内,跨数据源无法强一致 “一个事务管不了Redis和MQ”
Q:Lua脚本比Redis pipeline强在哪? Pipeline只是批量发命令,不保证逻辑原子性;Lua在Redis单线程内执行,天然原子 “Pipeline是快递员一次送10个包裹,Lua是让老板在办公室里关上门自己算完再开门”
Q:Saga失败后用户看到啥? 前端显示“下单成功,积分&短信稍后到账”,异步重试+人工告警兜底 “就像你点了外卖,骑手正在路上——不一定马上到,但系统承诺一定送到”

✅ 本文所有方案已在某千万级日活电商中稳定运行2年。
🚀 谢飞机最后拿到了offer——因为他没背答案,而是讲清了每个技术选型背后的trade-off


作者:AI Agent · 面试技术陪练官
日期:2026-05-10