面试题答案
一键面试设计与实现一致性保障机制
- 使用分布式事务框架:例如采用Seata框架,它提供了AT模式来处理分布式事务。在订单处理场景中,Seata可以协调Redis事务和MySQL数据操作。
- 业务流程:
- 应用程序发起订单处理请求,Seata的TC(事务协调器)开始管理这个全局事务。
- 首先执行Redis事务,Redis中的操作可以被视为一个分支事务。Seata的RM(资源管理器)记录Redis操作日志,若Redis事务成功,RM向TC报告分支事务成功。
- 接着执行MySQL数据操作,同样作为一个分支事务,MySQL的RM记录操作日志。若MySQL操作成功,RM向TC报告分支事务成功。
- 当所有分支事务都报告成功,TC发起全局事务提交,完成订单处理。
- 异常处理:若Redis或MySQL任何一方的分支事务失败,TC会发起全局事务回滚。RM根据记录的日志进行数据回滚,确保Redis和MySQL的数据一致性。
- 业务流程:
- 本地消息表方案:
- 设计消息表:在MySQL中创建一个消息表,用于记录订单处理的消息。消息表结构可包含消息ID、订单ID、消息状态(待处理、处理中、成功、失败)等字段。
- 业务流程:
- 应用程序创建订单时,先在MySQL中插入一条消息记录,状态设为“待处理”。
- 接着执行Redis事务,成功后更新消息表状态为“处理中”。
- 然后执行MySQL订单详细信息插入操作,成功后再次更新消息表状态为“成功”。
- 异常处理:
- 若Redis事务失败,应用程序可以根据消息表中“待处理”状态的记录,重新尝试Redis事务。
- 若MySQL订单详细信息插入失败,应用程序可以根据“处理中”状态的记录,进行数据回滚(例如删除Redis中相关订单数据),并重试MySQL操作。可以通过定时任务扫描消息表中状态为“失败”或长时间处于“处理中”的记录,进行补偿操作。
- 基于MQ的最终一致性方案:
- 引入消息队列(MQ):如Kafka、RabbitMQ等。
- 业务流程:
- 应用程序发起订单处理请求,先将订单相关消息发送到MQ。
- 消费者从MQ中获取消息,执行Redis事务,成功后执行MySQL数据操作。
- 异常处理:
- 若Redis事务失败,消费者可以根据业务逻辑决定是否重试。若重试多次仍失败,可以将消息发送到死信队列,进行人工干预。
- 若MySQL操作失败,同样可以重试。同时,MQ的消息确认机制可以确保消息不会丢失,保证最终一致性。
异常处理与数据回滚细节
- Redis事务异常:
- 回滚Redis事务:Redis本身支持事务回滚,若事务执行过程中某个命令失败,整个事务可以回滚,恢复到事务开始前的状态。
- 处理MySQL数据:若Redis事务失败,且MySQL已进行部分操作,根据上述方案进行处理。如使用Seata框架,TC会发起全局回滚;使用本地消息表方案,应用程序根据消息表状态决定是否回滚MySQL数据;使用MQ方案,消费者可重试或处理失败消息。
- MySQL数据操作异常:
- 回滚MySQL数据:MySQL支持事务回滚,通过
ROLLBACK
语句可以撤销未提交的事务操作。 - 处理Redis数据:同样根据不同方案,如Seata框架全局回滚会涉及Redis数据回滚;本地消息表方案中应用程序会删除Redis相关数据;MQ方案中消费者可决定是否删除Redis数据或重试。
- 回滚MySQL数据:MySQL支持事务回滚,通过
- 系统故障:
- 恢复机制:无论是使用分布式事务框架、本地消息表还是MQ方案,都需要有一定的恢复机制。例如,系统重启后,Seata框架会恢复未完成的事务;本地消息表方案通过定时任务扫描处理未完成的消息;MQ方案通过消费者重新消费未确认的消息,确保数据一致性。