分布式系统事务一致性解决方案01

Owen Jia 2018年12月06日 183次浏览

背景

传统的事务模式是在一个系统内部进行事务提交回滚控制。

传统单系统事务:通过程序抛出异常,让事务回滚数据库操作即可。

对于分布式系统来说,一个事务的执行需要调用多个子系统的接口,是无法保证其他系统的事务回滚的。目前并没有好的方案来保证分布式系统事务,大多数公司是采用补偿方案来保证事务的一致性。也有不少采用允许数据冗余的方案处理分布式系统,对于没有严格要求的业务也是可以的,但对于转账|订单等都很严格不允许数据不一致。

事务补偿的理念:

所谓补偿:一个正向的业务逻辑同时写一个反向的业务逻辑,当调用者的事务回滚要求是调用反向业务逻辑。对于补偿一般有现实时和非实时的场景。

在业务执行出错时:
1、先系统本地事务回滚,@Transcational方法抛出异常通过事务管理器回滚;
2、再调用其他系统的反向业务接口回退之前的正向业务;

实时:对于系统A的事务回滚同时要求其他子系统的反向接口等待反馈。
非实时:系统A的事务回滚后异步执行其他子系统反向接口不等待反馈。

通过MQ实现方案

通过MQ来实现事务回滚,可以很好的解决压力和阻塞情况。如下:

MQ分布式事务架构

具体流程如下:

  • Service a 执行一个完整事务需步骤1和2,Service b执行会调用Service c执行步骤3;
  • 当Service a 异常发生需要主动发送事务回滚消息 1 back 和 2 back给MQ;
  • MQ推送 mq 2 back 消息给Service d去执行业务回滚;
  • MQ推送 mq 1 back 消息给Service b去执行业务回滚;
  • Service b发送 3 back 消息给MQ;
  • MQ推送mq 3 back 消息给Service c执行业务回滚;

实现思路

具体实现接口需要考虑接口数据的存储引入中间件Redis,这点根据自己公司的具体情况来定。

分布式事务架构

service a-b-c-d:代表4个独立的微服务,包括数据库和部署都是独立体系。一个完整的业务流程是service a执行步骤1、3,其中步骤1会调用service b执行步骤2。将接口的消息存储在redis中,使用topic_name作为key。

这是个支持回退的事务接口,如下:

public class IHelloServiceImpl implements IHelloService{
	//问候话
	public Result sayHello(TalkModel talkModel,String topicName) throw DubboResultException;
	//收回说过的问候话
	public Result backSaidHello(TalkModel talkModel) throw DubboResultException;
}

MQ监听程序,如下:

public class MqServiceListener {
	public void handler(String topicName){
		//根据topicName前缀区分调用哪个接口,推荐用方法名作为topicName前缀
		//例如:backSaidHello_111111_0010
		String methodName = topicName.split("_")[0];
		if(methodName.equles(BackTopicMethod.backSaidHello.name())){
			TalkModel talkModel = (TalkModel) RedisUtil.getModel(topicName);
			Result result = IHelloService.backSaidHello(talkModel);
			//...
		}
	}
}

以“1”来细说流程:
1、service-a 调用 service-b 的接口 sayHello(..);
1、service-b 将 sayHello(..) 接口的参数 talkModel 存在 Redis 中,以 topicName 为key并设置有效期24小时;
2、service-a 发生事务回滚,向 MQ 推送 topicName 消息;
3、service-b 监听程序接受到 MQ 推送的 topicName 消息,去 Redis 取key为 topicName 的接口参数 talkModel;
4、service-b 分发执行 backSaidHello(..) 接口;

推荐建立:

分布式系统事务回滚消息监控中心,实时掌握消息处理进度。


技术的路上我们风雨同行,感谢你们的支持。

作者:Owen Jia, 推荐关注他的博客:Owen Blog