概述
2PC常用来实现分布式事务。分为请求-提交或者请求-终止
一般分为协调器C和若干事务执行者Si两种角色,这里的事务执行者就是具体的数据库,协调器可以和事务执行器在一台机器上。
事务执行者就是指真正的能够实现事务控制的,维护数据的对象。比如数据库,比如消息队列等等。
协调器:分布式环境下的事务管理肯定是需要一个协调核心的。
工作流程
1、我们的应用程序(client)发起一个开始请求到TC;
2、TC先将prepare消息写到本地日志,之后向所有的Si发起prepare消息【预备消息,要你干活了,打起精神】
以支付宝转账到余额宝为例,TC给A的prepare消息是通知支付宝数据库相应账目扣款1万,TC给B的prepare消息是通知余额宝数据库相应账目增加1w。
为什么在执行任务前需要先写本地日志,主要是为了故障后恢复用,本地日志起到现实生活中凭证 的效果,如果没有本地日志(凭证),出问题容易死无对证; 【所以很多时候都是先记日志后操作】
3、Si收到prepare消息后,执行具体本机事务,但不会进行commit,如果成功返回yes,失败返回no。同理,返回前都应把要返回的消息写到日志里,当作凭证。
4、TC收集所有执行器返回的消息,如果所有执行器都返回yes,那么给所有执行器发生送commit消息,执行器收到commit后执行本地事务的commit操作;如果有任一个执行器返回no,那么给所有执行器发送abort消息,执行器收到abort消息后执行事务abort操作【事务回滚】。
事务日志的作用
TC或Si把发送或接收到的消息先写到日志里,主要是为了故障后恢复用。如某一Si从故障中恢复后,先检查本机的日志,如果已收到commit ,则提交,如果abort 则回滚。如果是yes,则再向TC询问一下,确定下一步。如果什么都没有,则很可能在prepare阶段Si就崩溃了,因此需要回滚。
2PC总结
一个反对直接回滚,事务协调器向每一个事务执行者发送prepare消息,执行成功的事务返回yes,执行失败的事务返回no,全部成功TC发送commit命令,有一个节点执行失败就发送abort事务终止的命令。
由于2PC两阶段提交的性能太差,不适合高并发的系统。
如果使用Java,那么可以使用 开源软件atomikos(http://www.atomikos.com/) 来快速实现基于两阶段提交的分布式事务。