当前位置: 首页 > 后端技术 > Java

分布式事务(三)三阶段提交

时间:2023-04-01 18:59:44 Java

三阶段提交(3PC)是两阶段提交(2PC)的改进版。三阶段提交协议主要是为了解决两阶段提交协议的阻塞问题。2pc存在的问题是当coordinatorcrash时,参与者无法做出最终的选择。因此,参与者可能会一直处于阻塞状态,直到协调器恢复。三阶段提交是两阶段提交(2PC)的改进版本。三阶段提交3PC与两阶段提交的区别在于三阶段提交有两个变化:引入了超时机制。同时在协调者和参与者中引入超时机制;在第一阶段和第二阶段插入一个准备阶段。保证每个参与节点的状态在最终提交阶段之前是一致的。3PC将2PC的准备阶段再次一分为二,这样三阶段提交就有了三个阶段:CanCommit、PreCommit、DoCommit。2PC在CanCommit阶段之前的第一个阶段是本地事务执行完成后,最后不做commit,等其他服务执行完成返回Yes后才执行commit。而这里的CanCommit指的是尝试获取数据库锁,如果可以则返回Yes。该阶段主要分为事务查询两个步骤:协调者向参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应;响应反馈:参与者收到CanCommit请求后,正常情况下,如果参与者认为交易可以成功执行,会返回Yes响应,进入就绪状态。否则,反馈No。PreCommit阶段在Phase1,如果所有参与者都返回Yes,则进入PreCommit阶段进行事务预提交。这里的PreCommit阶段和上面的第一阶段类似,只是协调者和参与者都引入了超时机制(在2PC中只有协调者可以超时,参与者没有超时机制),主要包括两个步骤:transactionPre-commit:参与者收到PreCommit请求后,将执行事务操作,并在事务日志中记录undo和redo信息。响应反馈:如果参与者成功执行交易操作,将返回ACK响应并开始等待最终命令。如果任何参与者向协调器发送No响应,或者等待超时后,协调器没有收到参与者的响应,则事务中断:发送中断请求:协调器向所有参与者发送中止请求。中断事务:参与者收到协调器的中止请求后(或超时后,尚未收到协调器的请求),中断事务。DoCommit阶段,这个阶段真正的事务提交,也可以分为以下两种情况。执行提交,发送提交请求Coordinator收到参与者发送的ACK响应,然后他将从预提交状态进入提交状态。并向所有参与者发送doCommit请求。事务提交:参与者收到doCommit请求后,执行一次正式的事务提交。并在完成事务提交后释放所有事务资源。响应反馈:事务提交后,向协调器发送Ack响应。完成交易:协调者收到所有参与者的ack响应后,交易完成。中断事务,如果协调器没有收到参与者发送的ACK响应(可能是接收方没有发送ACK响应,或者响应超时),那么就会执行中断事务。发送中断请求:协调器向所有参与者发送中止请求事务回滚:参与者收到中止请求后,使用阶段2记录的undo信息执行事务回滚操作,并释放所有业务资源。反馈结果:参与者完成事务回滚后,向协调器发送ACK报文中断事务:协调器收到参与者反馈的ACK报文后,中断事务。总结与2PC相比,3PC主要解决单点故障问题,减少阻塞,因为参与者一旦不能及时收到协调者的信息,就会默认执行commit。而不是一直持有事务资源并处于阻塞状态。但这种机制也会造成数据一致性问题,因为由于网络原因,协调者发送的中止响应没有被参与者及时收到,所以参与者等待超时后才执行commit操作。这样,其他接收到中止命令并执行回滚的参与者之间就会出现数据不一致的情况。在2PC中,参与者的状态只有自己和协调者知道。如果协调者提出自己宕机,而一个参与者在协调器备份启用前宕机,其他参与者将进入既不能回滚也不能强制提交的阻塞状态,直到参与者从宕机中恢复。如果参与者在不同阶段宕机,我们看3PC如何应对:第1阶段:协调者或协调者备份没有收到宕机参与者的投票,直接中止交易;宕机参与者恢复后,readLogging发现没有发出投票,自行中止交易。Phase2:coordinator没有收到downparticipant的precommitACK,但是因为之前已经收到downparticipant的approval反馈(否则不会进入phase2),coordinatorcommit;coordinatorbackup可以通过询问其他参与者获得这些信息,过程是一样的;宕机参与者恢复后发现自己收到了预提交或者投了赞成票,自己会提交事务Phase3:即使协调者或者协调者备份没有收到宕机参与者t的commitACK,交易将结束;停机参与者如果在恢复后发现收到了提交或预提交,也会提交事务。我是狐神,欢迎大家关注我的微信公众号:wzm2zsd本文首发于微信公众号,版权所有,禁止转载!