SAGA pattern: Ti -> Ci 与Ci -> Ti 需要有相同endstate

今天课里讲到 券商系统与Sage。

这个是slide截图:

T1:券商预留资金
C1:券商接触预留
T2: 券商确认订单
C2:券商取消订单
这里 T1->C1与C1->T1执行结果并不一样,同理T2->C2与C2->T2.

[1] 中有举例

举例说明,还是考虑Ti执行超时的场景,我们采用了backward recovery,发送一个Ci,那么就会有三种情况:

  1. Ti的请求丢失了,服务之前没有、之后也不会执行Ti
  2. Ti在Ci之前执行
  3. Ci在Ti之前执行

#3 这种情况确实可能在我们课堂讨论的设计中出现,这里使用SAGE pattern是不是会出问题?

[1] 分布式事务:Saga模式 - 简书

我们在 compensate 之前需要对系统的状态有确定的了解,即Ti请求丢失了具体是因为什么原因,不应该允许在Ti仍可能被执行的情况了运行 Ci。

谢谢。

Ti请求丢失了具体是因为什么原因

这里我们首先需要确定Ti请求丢失了,然后再去分析原因。但是由于network的不稳定性,Ti请求(理论上)可以在任何时候送达服务器。怎么处理这种情况呢?

我想到两个方案:

  1. 服务器执行Ci请求前必须保证对应的Ti请求已执行,否则do nothing。
  2. 设置一个Ti请求的timeout,超过timeout则被认为丢失了,即便服务器之后收到Ti请求也不再执行。但是这里的问题是用户和服务器的clock很可能不同步。

#1可行吗

这个 Saga 的运行跟用户发送的Request 是Async的,所以不牵涉到用户clock不准的问题。当服务器接受到用户发送Request的时候,用户端会收到“确认收到到Request”,然后服务器端开始 Async 运行 Saga。我们是可以通过查询数据库状态来明确知道 T1 有没有执行的,如果 Ti 被执行了,我们才有可能运行 Ci 来退回。如果没有被执行,Ci 不需要执行,但需要运行 Ci-1, Ci-2 … C1.

1 个赞