分布式系统中的每个节点都能知道自己的事物是成功还是失败,但是不知道其他节点的操作结果。要保证多个节点的事务性,就需要一个中间者来协调这些机器,由中间者来决定事物的提交。2pc和3pc应运而生。
2PC
过程如下
- 中间者向每个节点发送事物请求
- 每个节点执行事物操作,将undo和redo记录下来,并将自己的执行结果返回给中间者
- 如果都执行成功,则中间者向各个节点发送提交请求,节点们执行事务提交操作,并发送ack给中间者;如果有任意一个节点失败,则中间者向各个节点发送回滚请求,节点们执行回滚操作,并发送ack给中间者。
他的缺点也很明显:中间者是单点,节点会阻塞,可能只有一部分节点收到commit请求
3PC
过程如下
- 中间者向所有节点发送cancommit请求,询问是否可以执行事务提交操作
- 如果所有节点都返回成功,中间者会发送precommit请求,节点们会执行事务操作,将undo和redo记录下来,并将自己的执行结果返回给中间者,等待最后的提交或者终止;如果任一节点返回失败或者中间者在超时时间内没收到节点的返回,会发送终止请求,节点们中断事务。如果节点们在超时时间内没收到中间者发送的precommit阶段的请求(包括正常的precommit请求或者中断请求),也会中断事物。
- 此阶段在成功发送precommit请求之后。如果任一节点返回失败或者中间者在超时时间内没收到节点的返回,中间者会向所有节点发送终止请求,节点们收到终止请求会中断事物,利用undo执行回滚操作,返回ack;如果全都返回成功,中间者发送docommit请求,节点们正式提交事务,返回ack。因为各种原因导致的节点无法在超时时间内收到中间者发送的提交或者终止请求,节点都会进行事务提交
缺点也很明显了:在第三步如果中间者发送的终止操作无法在超时时间内到达节点的话,节点也会执行提交,数据会不一致