一 、事务处理
1 基于可靠消息服务的方案:使用消息中间件来实现这种分布式事务
例子:假设有A和B两个系统,分别可以处理任务A和任务B,此时存在一个业务流程,需要将任务A和任务B在同一个事务中处理。此时就可以使用消息中间件来实现这种分布式事务的处理。
步骤:
- 在系统A处理任务A前,首先向消息中间件发送一条消息
- 消息中间件收到后将该条消息持久化,持久化成功后,向A回复一个确认应答
- 系统A收到确认应答后,则可以开始处理任务A
- 任务A处理完成后,向消息中间件发送Commit或者Rollback请求。该请求发送完成后,对系统A而言,该事务的处理过程就结束了
- 如果消息中间件收到Commit,则向B系统投递消息;如果收到Rollback,则直接丢弃消息。
- 如果消息中间件收到确认应答后便认为该事务处理完毕
- 如果消息中间件在等待确认应答超时之后就会重新投递,直到下游消费者返回消费成功响应为止
2 TCC实现分布式事务
TCC三个步骤:
- Try操作,负责资源的检查和预留
- Confirm操作作为二阶段提交操作,执行业务
- Cancel是预留资源的释放;
TCC例图(下订单/减库存为例):
Try
下单业务由订单服务和库存服务协同完成,在try阶段订单服务和库存服务完成检查和预留资源。
订单服务:检查当前是否满足提交订单的条件
库存服务:检查当前是否有充足的库存,并锁定资源。
Confirm
订单服务和库存服务成功完成Try后开始正式执行资源操作。
订单服务:向订单写一条订单信息。
库存服务:减去库存。
Cancel
如果订单服务和库存服务有一方出现失败则全部取消操作。
订单服务:删除新增的订单信息。
库存服务:减去的库存再还原。
3 最大努力通知方案
最大努力的将消息通知给接收方,当消息无法被接收方接收 时,由接收方主动查询业务处理结果
1、业务方将短信发送请求提交给短信平台
2、短信平台接收到要发送的短信,记录到数据库中,并标记其状态为”已接收"
3、短信平台调用外部短信发送供应商的接口,发送短信。外部供应商的接口也是异步将短信发送到用户手机上,因此这个接口调用后,立即返回,进入第4步。
4、更新短信发送状态为"已发送"
5、短信发送供应商异步通知短信平台短信发送结果。而通知可能失败,因此最多只会通知N次。
6、短信平台接收到短信发送结果后,更新短信发送状态,可能是成功,也可能失败(如手机欠费)。到底是成功还是失败并不重要,重要的是我们知道了这调短信发送的最终结果
7、如果最多只通知N次,如果都失败了的话,那么短信平台将不知道短信到底有没有成功发送。因此短信发送供应商需要提供一个查询接口,以方便短信平台驱动的去查询,进行定期校对。
二、 2PC的改进(3PC)
2pc存在的一个问题:协调者不给参与者信号会长时间阻塞,并长时间占有资源
等待超时之后 协调者没有接受到所有参与者的反馈响应,那么就会中断事务或者回滚事务 、并释放资源
3pc的流程:
一阶段:先由协调者向参与者发送询问信号,检查是否具备执行条件,在回复协调者(而2PC是真实获取锁占用资源);如果存在参与者不具备执行条件,那么协调者就会发送信号给所有参与者,告知本次事务取消了
二阶段:参与者收到协调者指令后进行本地事务执行,且将执行结果反馈到协调者,来做决策。(如果存在部分参与者无法执行事务的情况,参与者本地回滚,释放资源,取消本次事务)
三阶段:参与者全部完成本地事务执行但是没有提交,并且都给协调者反馈,在提交阶段协调者向参与者发送提交指令,参与者收到之后开始执行本地提交,并反馈结果