> For the complete documentation index, see [llms.txt](https://xiang753017.gitbook.io/zixiang-blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://xiang753017.gitbook.io/zixiang-blog/patterns/distributed-transaction-design.md).

# Distributed Transaction Design

### Assumptions

\[1] 從一整套系統中，主要會有兩層 Upper 與 Lower 兩層，Lower Layer 需要考慮不同流量進行 scale，Upper Layer 負責純粹的 Business Logic。&#x20;

1. Upper Layer:
   1. Scale agnostic: 無關規模/流量，整體業務程式架構都不會因而改變
   2. 實務上Upper 為商業邏輯層
2. Lower Layer：
   1. Scale Aware: 具備規模感知，能隨著流量進行動態調整的架構。
   2. 進行擴展面的基礎邏輯。 ex, Database CRUD 等等

<figure><img src="/files/dRC4GtFtBUtyeb8BWCw7" alt=""><figcaption><p>[1]  figure 1</p></figcaption></figure>

然而在 Distribution System 中且以無限擴展為目標的話，重點會是在於 Lower Layer 的基礎設計。在這樣的設計之中，通常會有以下慣例：

1. **At Least Once Message**
   1. 基於網路不可靠的原則，在無限擴展的架構下，訊息通常不會只送一次。藉此保證訊息一定會送達。
2. **Atomic Transactions Cannot Span Entities**
   1. 基於網路不可靠的原則，企圖跨 Entity 進行 Transaction 來達到 Atomicity 的效果是不可行的。一旦發生網路延遲，會造成 Transaction 阻塞並影響其他服務。
3. **Messages Are Addressed to Entities**
   1. 在無限擴展架構下，Entity 必須考慮 Database Partition 的場景，Message 本身就需要能夠解析該 Entity 是在哪一個 Partition，否則同樣會造成阻塞並影響其他服務。

### Distribution Components&#x20;

最小單位為 Entity，而跨 Entity 的互動狀態在 Entity 內部持久化的紀錄稱為 Activity

#### Def of Entity:

1. First, the data encapsulated by the object must be strictly disjoint from all other data. &#x20;
2. that disjoint data may never be atomically updated with any other data.

Entity 的概念與 Domain Driven Design 中所描述的定義相同，需要具備以下條件:

1. 有 ID 的概念
   1. id 往往是 Partition key
   2. 唯一值且代表該entity
2. 封裝業務邏輯
3. 具備 Transaction Boundary:
   1. Entity 在無限擴展的架構下，只會保證自身具備 automicity 的特性。為了避免 global lock 或者網路延遲，使得整個系統被拖慢。

#### Def of Activity

That two-party knowledge maintained inside an entity is what we call an activity.

在內部邏輯需要考慮以下事情：

1. Retries and Idempotency
   1. Retries
      1. 為了要達到 retries 會沒有問題，我們要透過 `Idempotency` 去達到
   2. Idempotency
      1. Nature: 不論執行幾次，結果都一樣。
      2. Remembering Messages as State: 當一個 Entity 收到訊息時，會將 message id 以及處理結果，作為該 Entity 自身狀態的一部分儲存起來。
      3. Ensuring At-Most-Once Acceptance via Activities: Entity 透過 Activities 怎麼做到，是透過紀錄外部 rpc 的訊息狀態，用來知道當前訊息是否已被處理，防止retry 的副作用。
2. Coupling WITHOUT Atomicity
   1. Uncertainty at a Distance: 包裹 transaction 之後，有可能會因為網路造成`Transaction`  整體速度變慢，進而影響整體。系統會陷入無法得知對方最終結果的「不確定狀態」，進而引發 Distributed Lock 阻塞。
   2. Activities and the Management of Uncertainty
      1. 透過 Activity 本身就會記錄 partner party，這個狀態本身就能夠`管理`不確定因素。
   3. Performing Tentative Business Operations
      1. 從 b 點來看，接受 Tentative 狀態來管理不確定因素，是唯一的解方。實務上 event driven 就是一個經典的 architecture 的做法。
      2. Entity 內部須實作 Tentative、Confirmation 與 Cancellation 的狀態機。最終 Entity 透過先發起可逆的操作，拉長容忍不確定性的時間，直到取得最終結果才進行 Confirm 或 Cancel。
   4. Uncertainty and Almost-Infinite Scaling
      1. Almost-Infinite Scaling 架構中，不確定性是必須被考慮且無法消除的因素
      2. 放棄 global consistence 走向 eventually consistence 在無限闊展的場景是必然結果

### Reference

\[1] Helland, Pat. "Life beyond distributed transactions: an apostate’s opinion." *Queue* 14.5 (2016): 69-98.
