补偿事务模式
Compensating Transaction Pattern
撤消由一系列步骤执行的工作,如果一个或多个步骤失败,这些步骤共同定义最终一致的操作。
1. 背景与问题⚓
运行在云上的应用经常修改数据,数据可能跨越多个数据源与地区。为了避免在诸如分布式系统中竞争和提升性能,应用不应该企图提供强一致性功能,而是应该采用最终一致性模型。在这个模型下,一个经典的业务操作可能包含了一系列独立的步骤。虽然这些步骤在执行的时候从全局视角来看是不一致的,但当操作完成时并且所有的步骤都执行完毕后系统应该再次变为一致的。
一个严峻的挑战是最终一致性模型如何处理不可恢复的步骤。在这种情况下也许需要撤销所有先前已完成的步骤。但是数据不能简单的回滚,因为其他并行的应用实例可能已经改变它了。即使数据没有被并行实例所改变,撤消一个步骤可能也不是一件简单的事情。有必要应用各种特定于业务的规则。
如果一个实现了跨越几个数据源的最终一致性操作,撤消步骤会要求轮流访问这些数据源。必须可靠地撤消在每个数据源中执行的工作,以防止系统保持不一致。
并非所有被一个实现了最终一致性操作影响的数据都存在数据库中。在一个面向服务(Service Oriented Architecture (SOA))的架构环境中,一个操作可能导致一个服务的动作,然后引起那个服务的状态改变。为了撤消这个操作,状态改变也必须要撤消。这可能导致级联的影响更改。
2. 解决方案⚓
实现一个补偿事务。一个补偿事务的步骤必须撤消这些步骤在原操作中造成的影响。一个补偿事务可能不能简单地使系统恢复原样,但是必须有一个智能的处理流程,考虑到并发实例所做的任何工作。这个流程通常是特定于应用的,由原始操作执行的工作性质驱动。
实现需要补偿的最终一致性操作的常见方法是使用工作流。随着原始操作的进行,系统会记录有关每个步骤的信息以及如何撤消该步骤执行的工作。注意撤消工作可能并不需要遵从原始操作的精确镜像顺序,也可能并发执行。
补偿事务自己也是最终一致性的,也可能会失败。系统应该能够在失败点恢复补偿事务并继续。它可能需要重复失败的步骤,所以补偿事务的步骤应该是幂等的。
在某些情况下,可能无法从失败的步骤中恢复,除非通过手动干预。此时系统应该抛出警告并为失败提供尽可能多的信息。
3. 适用场景⚓
适用:
只有操作失败时必须回滚的情况。设计解决方案应尽可能避免要求补偿事务的复杂性。