#JAVA破局之路#分布式事务解决方案),分布式事务详解(mysql事务如何实现的( 四 )


·同步阻塞:在准备就绪之后 , 资源管理器中的资源一直处于阻塞 , 直到提交完成 , 释放资源 。
·数据不一致:两阶段提交协议虽然为分布式数据强一致性所设计 , 但仍然存在数据不一致性的可能 。 比如在第二阶段中 , 假设协调者发出了事务Commit的通知 , 但是因为网络问题该通知仅被一部分参与者所收到并执行了Commit操作 , 其余的参与者则因为没有收到通知一直处于阻塞状态 , 这时候就产生了数据的不一致性 。
两阶段提交方案锁定资源时间长 , 对性能影响很大 , 基本不适合解决微服务事务问题 。
2.33PC事务3PC , 全称“threephasecommit” , 是2PC的改进版 , 其将2PC的“提交事务请求”过程一分为二 。
#JAVA破局之路#分布式事务解决方案),分布式事务详解(mysql事务如何实现的
文章图片
2.3.1:第一个阶段:CanCommit1.事务询问:协调者向所有的参与者发送一个包含事务内容的canCommit请求 , 询问是否可以执行事务提交操作 , 并开始等待各参与者的响应 。
2.各参与者向协调者反馈事务询问的响应:参与者接收来自协调者的canCommit请求 , 如果参与者认为自己可以顺利执行事务 , 就返回Yes , 否则反馈No响应 。
这一阶段主要是确定分布式事务的参与者是否具备了完成commit的条件 , 并不会执行事务操作 。
2.3.2第二阶段:precommit协调者在得到所有参与者的响应之后 , 会根据结果执行2种操作:执行事务预提交 , 或者中断事务 。
1.执行事务预提交分为3个步骤:
·发送预提交请求:协调者向所有参与者节点发出preCommit的请求 , 并进入prepared状态 。
·事务预提交:参与者受到preCommit请求后 , 会执行事务操作 , 对应2PC中的“执行事务” , 也会Undo和Redo信息记录到事务日志中 。
·各参与者向协调者反馈事务执行的结果:如果参与者成功执行了事务 , 就反馈Ack响应 , 同时等待指令:提交(commit)或终止(abor) 。
2.中断事务也分为2个步骤:
·发送中断请求:协调者向所有参与者节点发出abort请求 。
·中断事务:参与者如果收到abort请求或者超时了 , 都会中断事务 。
2.3.3第三阶段:docommit1.执行提交
·发送提交请求:进入这一阶段 , 如果协调者正常工作 , 并且接收到了所有协调者的Ack响应 , 那么协调者将从“预提交”状态变为“提交”状态 , 并向所有的参与者发送doCommit请求 。
·事务提交:参与者收到doCommit请求后 , 会正式执行事务提交操作 , 并在完成之后释放在整个事务执行期间占用的事务资源 。
·反馈事务提交结果:参与者完成事务提交后 , 向协调者发送Ack消息 。
·完成事务:协调者接收到所有参与者反馈的Ack消息后 , 完成事务 。
2.中断事务(假设有任何参与者反馈了no响应 , 或者超时了 , 就中断事务) 。
·发送中断请求:协调者向所有的参与者节点发送abort请求 。
·事务回滚:参与者接收到abort请求后 , 会利用其在二阶段记录的undo信息来执行事务回滚操作 , 并在完成回滚之后释放整个事务执行期间占用的资源 。
·反馈事务回滚结果:参与者在完成事务回滚之后 , 向协调者发送Ack消息 。
·中断事务:协调者接收到所有的Ack消息后 , 中断事务 。
2.3.4与与2pc的区别注意:在阶段三 , 可能会出现2种故障:协调者出现问题/协调者和参与者之间的网络故障一段出现了任一一种情况 , 最终都会导致参与者无法收到doCommit请求或者abort请求 , 针对这种情况 , 参与者都会在等待超时之后 , 继续进行事务提交 。
优点:
相比较2PC , 最大的优点是减少了参与者的阻塞范围(第一个阶段是不阻塞的) , 并且能够在单点故障后继续达成一致(2PC在提交阶段会出现此问题 , 而3PC会根据协调者的状态进行回滚或者提交) 。