云计算设计模式(四)Compensating Transaction/事务补偿模式
模式描述
包含多个步骤的事务,如果其中一个或者多个步骤失败,那么就需要处理每个步骤的取消操作。遵循最终一致性模型的操作,通常都是发生在云端应用中,执行复杂的业务逻辑和工作流。
上下文和问题
运行在云端的应用程序,通常会频繁的修改数据。这些数据可能分散地存储在不同的物理位置的不同的数据源中。为了防止分布式环境中的资源竞争和提升性能,应用程序不应提供强事务一致性。而是应该实现最终一致性。在这个模型中,一个典型的业务逻辑操作包含一系列分离的步骤,当这些步骤执行过程中,系统的整体状态是不一致的。但是,当所有的步骤都被成功执行,操作完成后,系统状态会再次恢复一致。
Data Consistency Primer描述了为什么分布式事务伸缩性不好,和最终一致性模型所遵循的相关原则。
最终一致性模型的挑战是,如何处理一个失败的步骤。在这种情况下,可能需要取消操作中之前已经完成的步骤。然而,数据不能简单地回滚,因为其他并发的应用实例可能已经修改了这个数据的值。即使数据没有被其他并发的应用实例修改,取消一个步骤也能也不是恢复原始数据那么简单,可能需要应用各种业务特定的规则。
如果一个实现了最终一致性的操作,跨越了多个异构的数据存储,那么事务需要操作的步骤,可能需要依次访问每个数据存储。这些数据存储都必须支持可靠的数据取消操作,以防止出现数据不一致的问题。
不是所有最终实现一致性的操作所影响的数据,都可以保存在数据库中。在SOA环境中,一个操作可能调用服务的一个Action,这导致了服务中状态的改变。要取消这个操作,服务的状态也必须可以回退。这可能通过再次调用服务,并执行服务的另外一个操作,来推翻第一个操作的影响。
解决方案
这个解决方案是实现补偿事务(事务补偿机制)。补偿事务中的步骤,必须取消原步骤中的操作所造成的影响。补偿事务可能无法简单地用事务步骤未执行前的状态,替换当前状态。因为这种方式可能会覆盖应用程序中并发的操作对这个状态的修改。相反的,它应该是一个智能的过程,要考虑在这个期间其他并发实例所做的工作。这个过程通常是应用程序特定的,由原始操作所做的工作来驱动。
通常的方式是,使用一个工作流来实现要求补充的最终一致性操作。在原始操作执行过程中,系统记录了这些步骤的信息,以及这些已经处理的步骤怎样被取消。如果在某个时刻一个步骤执行失败,工作流将倒回已经完成的步骤的每一步,处理每个步骤的取消操作。要注意的是,补偿事务可能不会按照步骤执行的顺序来处理这些步骤的取消操作。可能会并行的处理某些取消操作。
补偿事务也是一个最终一致性操作,也可能会失败。系统应该有能力重复执行在某个点上失败的补偿事务,可能需要重复执行失败的步骤,因此,补偿事务中的步骤应该是幂等命令,更多的信息,请参考幂等模式。
在某些情况下,事务不可能从一个步骤中恢复,除非进行人工干预。在这种情况下,系统应该抛出一个警告信息,并提供关于失败原因的足够的信息。
问题和注意事项