面试题答案
一键面试事务拆分方案
- 按业务模块拆分:将商品库存管理、订单生成、用户积分计算分别作为独立事务。例如,订单生成事务仅处理订单表、订单详情表等与订单直接相关的表操作;商品库存管理事务专注于商品库存表等相关表。这样可避免一个业务模块的事务影响其他模块,减少事务锁的范围和时间。
- 进一步细分事务:对于复杂业务模块,可按操作步骤细分。如订单生成中,先创建订单记录(一个事务),再处理库存扣减和积分计算(分别为不同事务),只要保证最终一致性即可。
锁的粒度控制
- 行级锁:在库存管理中,对具体商品的库存操作使用行级锁。例如,当某商品库存扣减时,仅锁定该商品库存对应的行记录,而不是整个库存表,这样其他商品的库存操作可并发进行。
- 表级锁:在一些特殊场景,如批量处理少量表且操作关联性强时,使用表级锁。例如,当进行订单状态批量更新(涉及订单表和订单状态历史表等少量表)时,可使用表级锁,减少锁的开销。但要注意尽量缩短表级锁的持有时间。
- 读写锁:对于读多写少的场景,如商品详情查询(读操作)和商品信息更新(写操作),使用读写锁。读操作时允许多个线程同时读取数据,写操作时则独占锁,确保数据一致性。
并发访问时的数据保护机制
- 乐观锁:在库存扣减场景,使用乐观锁。例如,库存表增加版本号字段,每次更新库存时,先读取当前版本号,更新时带上版本号,若版本号一致则更新成功并递增版本号,否则重试。这样减少锁等待时间,提高并发性能。
- 排队机制:对于高并发的关键操作,如热门商品库存扣减,可引入排队机制,如使用消息队列(如 Kafka)。将库存扣减请求发送到队列,系统按顺序处理队列中的请求,避免大量并发请求同时竞争锁。
- 数据校验和补偿机制:在事务结束后,进行数据校验,若发现数据不一致,通过补偿机制进行修复。例如,订单生成成功但库存扣减失败,可通过定时任务或人工干预进行库存补偿。
监控和调优
- 监控指标:
- 数据库层面:监控锁等待时间、锁争用次数、事务执行时间等。通过 MySQL 的
SHOW STATUS
等命令获取相关指标,或使用数据库监控工具(如 Prometheus + Grafana)。 - 应用层面:监控接口响应时间、吞吐量、并发请求数等。在代码中埋点收集数据,通过应用性能监控工具(如 New Relic)展示。
- 数据库层面:监控锁等待时间、锁争用次数、事务执行时间等。通过 MySQL 的
- 性能调优:
- 优化 SQL 语句:分析慢查询日志,优化复杂 SQL,添加合适索引。例如,在订单查询时,根据常用查询条件(如订单状态、下单时间)添加联合索引。
- 调整事务隔离级别:根据业务需求,适当降低事务隔离级别,如从
SERIALIZABLE
调整为READ COMMITTED
,减少锁争用,但要注意数据一致性问题。 - 增加缓存:对于读多写少的数据,如商品基本信息,使用缓存(如 Redis)。先从缓存读取数据,缓存失效时再从数据库读取并更新缓存,减轻数据库压力。
- 稳定性保障:
- 故障演练:定期进行故障演练,如模拟数据库故障、网络延迟等,检验系统的容错能力和恢复能力。
- 备份与恢复:建立完善的数据库备份策略,定期备份数据。同时测试恢复流程,确保在数据丢失或损坏时能快速恢复。