电商大促时,用户抢购同一件商品,库存却出现负数——这是典型事务失控的表现。MySQL事务的本质,是将多个SQL操作打包成一个不可分割的执行单元,要么全部成功,要么全部回滚。

2026AI生成图像,仅供参考
一个事务必须满足ACID特性:原子性(Atomicity)确保操作全做或全不做;一致性(Consistency)保证数据库从一个合法状态转入另一个合法状态;隔离性(Isolation)防止并发操作互相干扰;持久性(Durability)确保提交后数据不丢失。其中,隔离性在高并发场景下尤为关键。
MySQL默认的REPEATABLE READ隔离级别能避免脏读和不可重复读,但仍有幻读风险。电商下单常需严格防超卖,仅靠SELECT + UPDATE易出错。应使用SELECT … FOR UPDATE,在查询同时加行级写锁,锁定库存记录直到事务结束。
更稳妥的做法是结合“减库存+订单生成”为原子操作。例如:UPDATE product SET stock = stock – 1 WHERE id = 1 AND stock >= 1;通过WHERE条件校验库存,再用ROW_COUNT()判断是否影响了1行。若返回0,说明库存不足,直接拒绝下单,避免锁等待与死锁。
长事务是性能杀手。支付回调、物流同步等外部依赖一旦超时,可能让锁持有过久,阻塞其他请求。务必设置合理超时:innodb_lock_wait_timeout调至10–30秒,应用层配合try-catch捕获DeadlockException并自动重试(限1–2次)。
实际部署中,建议将库存扣减放在独立微服务中,配合Redis预扣减(缓存库存)做第一道过滤,MySQL仅作最终一致校验。这种“缓存+DB双写+事务补偿”的组合,既保障强一致性,又支撑万级QPS。
记住:事务不是银弹。过度依赖锁会扼杀并发能力;忽视隔离级别可能引发数据异常;盲目缩短事务则增加应用逻辑复杂度。真正进阶的站长,是在业务语义、数据库特性和系统性能之间,找到那个恰到好处的平衡点。