在微服务架构中,单个服务中的事务仍然可以使用ACID事务。然而,在对更新多个服务拥有的数据的操作实现服务时,必须使用一种消息驱动的本地事务序列来维护数据的一致性。
基于CAP理论知识,为了保障分布式系统的可用性,往往会放弃对数据强一致性的要求。但是为了解决在微服务架构下的数据一致性这个复杂问题,应用程序需要一些机制来保证。
一、维护数据一致性
在微服务架构中维护数据的一致性,它可以避免分布式事务带来的问题。由一连串的本地事务组成,需要更新多个服务中的数据。每一个本地事务负责更新它所在的服务的私有数据库,这些操作仍然依赖于我们所熟悉的ACID事务框架。当本地事务完成时,服务会发布消息。然后,此消息将触发下一个步骤的执行,使用消息不仅能够保障不同服务的本地事务之前的松散耦合,还可以保证整个链路调用顺利完成。
二、补偿事务做回滚操作
在ACID事务中,如果业务逻辑检测到违反业务规则,可以轻松回滚事务。基于消息驱动的本地事务序列无法自动回滚,因为每个步骤都会将其更改提交到本地数据库。
假设第 n+1 个事务失败了,必须撤销前 n 个事务的影响。从概念上说,就是每一个步骤上的事务,都有一个对应的补偿事务,它可以撤销其影响。并非所有的步骤都需要补偿事务,依据具体的业务使用场景来定。
三、协同式(简单场景)
协同式的本地事务序列使用发布/订阅的方式进行交互。
- 需要确保将更新其本地数据库和发布事件作为数据库事务的一部分;
- 确保必须能接收到每个事件映射到自己的数据上。
彼此之间订阅事件,通常会导致服务之间循环依赖的关系。毕竟循环依赖并不是一种好的设计风格。
四、编排式(复杂场景)
编排式的实现,首先需要创建一个编排器。编排器的建模方法是状态机,状态机由一个状态和一组事件触发的状态之间的转换组成。使用命令/异步响应的方式与事务的参与方服务通信。为了完成其中的一个事务环节,编排器对某一个事务参与方发出一个命令消息,告诉这个事务参与方该做什么操作。当事务参与方完成操作之后,会给编排器发一个答复消息。编排器处理这个消息之后,并决定下一步操作是什么。
编排器定义了很多状态转换,每个编排的步骤包括一个更新数据库和发布消息的服务。服务必须使用事务性消息,以便自动更新数据库并发送消息。