面试题答案
一键面试基于MySQL实现分布式事务方案
两阶段提交(2PC)
- 原理:
- 准备阶段(Prepare Phase):协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者回复。参与者执行事务操作,但不提交,记录undo和redo日志,然后向协调者反馈“可以提交”或“回滚”。
- 提交阶段(Commit Phase):如果所有参与者都回复“可以提交”,协调者向所有参与者发送“提交”指令,参与者收到后正式提交事务;如果有任何一个参与者回复“回滚”,协调者向所有参与者发送“回滚”指令,参与者回滚事务。
- 在Node.js中实现:可以使用Sequelize等ORM框架,结合MySQL数据库。协调者和参与者之间通过网络通信来实现2PC流程。例如,利用Node.js的网络模块(如
net
或http
)进行消息传递,在业务逻辑中实现准备和提交阶段的逻辑判断和操作。 - 优点:
- 简单,易于理解和实现。
- 保证了强一致性,在所有参与者都正常的情况下,能确保事务的原子性。
- 缺点:
- 单点故障:协调者故障会导致整个分布式事务无法继续,处于阻塞状态。
- 同步阻塞:在准备阶段和提交阶段,参与者都处于阻塞状态,等待协调者指令,降低系统并发性能。
- 数据不一致:在提交阶段,如果协调者发送“提交”指令后部分参与者未收到,可能导致数据不一致。
三阶段提交(3PC)
- 原理:
- 询问阶段(CanCommit Phase):协调者向参与者发送CanCommit请求,询问是否可以执行事务操作,参与者根据自身状态回复“可以”或“不可以”。
- 预提交阶段(PreCommit Phase):如果所有参与者都回复“可以”,协调者向参与者发送PreCommit请求,参与者执行事务操作但不提交,记录日志,然后回复“成功”或“失败”。
- 提交阶段(DoCommit Phase):如果所有参与者在预提交阶段都回复“成功”,协调者发送DoCommit请求,参与者提交事务;否则发送Abort请求,参与者回滚事务。在提交阶段,即使协调者故障,参与者根据自身超时机制也能做出相应处理,避免长时间阻塞。
- 在Node.js中实现:同样可借助Sequelize等框架,通过Node.js的网络通信模块实现各阶段的消息传递和逻辑处理。在不同阶段设置相应的定时器来处理超时情况。
- 优点:
- 减少单点故障影响:在提交阶段协调者故障时,参与者能根据超时机制自行决定是否提交,降低阻塞时间。
- 降低同步阻塞:询问阶段不执行事务操作,减少了参与者的阻塞时间。
- 缺点:
- 复杂性增加:相比2PC,增加了一个阶段,实现和维护更复杂。
- 仍然存在不一致风险:虽然降低了,但在极端情况下(如网络分区等)仍可能出现数据不一致。