分布式事务(概念)
事务有ACID的特性,即原子性、一致性、隔离性、持久性。
TCC编程:Try、Confirm和Cancel,分表代表尝试锁定资源、全部执行成功确认提交和取消。
分布式事务,是指多个任务分发到不同服务器执行,要么全部成功,要么全部失败。目前有几种方案,其中用的多且简单的就是补偿机制,以及2阶段提交、3阶段提交、4阶段提交。
补偿机制:以订单扣库存为例,若订单插入成功库存量扣失败,则mq定时补偿删除订单。即任何一个事务是可逆或可回滚的。
2阶段提交:请求阶段(协调者请求参与者决策是否可提交事务)、提交阶段(根据所有参与者的决策结果最终确认提交还是取消)。存在问题:1同步阻塞问题。执行过程中,所有参与节点都是事务阻塞型的。2单点故障。由于协调者的重要性,一旦协调者发生故障。3数据不一致。在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障。4当协调者出错,同时参与者也出错时,两阶段无法保证事务执行的完整性。
1)CanCommit阶段
3PC的CanCommit阶段其实和2PC的准备阶段很像。
协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。
2)PreCommit阶段
Coordinator根据Cohort的反应情况来决定是否可以继续事务的PreCommit操作。
根据响应情况,有以下两种可能。
A.假如Coordinator从所有的Cohort获得的反馈都是Yes响应,那么就会进行事务的预执行:
发送预提交请求。Coordinator向Cohort发送PreCommit请求,并进入Prepared阶段。
事务预提交。Cohort接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。
响应反馈。如果Cohort成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。
B.假如有任何一个Cohort向Coordinator发送了No响应,或者等待超时之后,Coordinator都没有接到Cohort的响应,那么就中断事务:
发送中断请求。Coordinator向所有Cohort发送abort请求。
中断事务。Cohort收到来自Coordinator的abort请求之后(或超时之后,仍未收到Cohort的请求),执行事务的中断。
3)DoCommit阶段
该阶段进行真正的事务提交,也可以分为以下两种情况:
执行提交
A.发送提交请求。Coordinator接收到Cohort发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有Cohort发送doCommit请求。
B.事务提交。Cohort接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。
C.响应反馈。事务提交完之后,向Coordinator发送ACK响应。
D.完成事务。Coordinator接收到所有Cohort的ACK响应之后,完成事务。
中断事务
Coordinator没有接收到Cohort发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。
三阶段提交协议和两阶段提交协议的不同:
对于协调者(Coordinator)和参与者(Cohort)都设置了超时机制(在2PC中,只有协调者拥有超时机制,即如果在一定时间内没有收到cohort的消息则默认失败)。
在2PC的准备阶段和提交阶段之间,插入预提交阶段,使3PC拥有CanCommit、PreCommit、DoCommit三个阶段。
PreCommit是一个缓冲,保证了在最后提交阶段之前各参与节点的状态是一致的。
消息事务(2阶段提交)+最终一致性:即本地事务和发消息放到一个分布式事务中,比如系统向消息系统发预备消息,发送成功才执行本地事务,执行成功才发送提交消息给中间件。若本地事务执行失败,则通过消息中间件回调接口,不断检查本地事务执行状态。若本地执行成功发送提交失败,其实通过中间件回调接口就检测成功就可以自动提交了。
消息系统(eBay模式):核心是保证服务接口的幂等性。即同一个接口重复调用也不会出问题,保证数据的唯一性。