在.NET中輕鬆執行多步原子操作

語言: CN / TW / HK

在分佈式的應用中,在微服務架構中,常常需要原子的執行多個操作,例如發佈文章後,需要更新相關的文章統計信息

解決上述多步原子操作的經典模式是發件箱模式,該模式的實現比較複雜,一方面要依賴消息隊列,另一方面還要管理定時輪詢任務,或者監聽數據庫的日誌,導致涉及多數據庫多租户的這種場景下,尤其難以部署和維護。

本文介紹的方案,以更簡單易用的架構,實現了多步原子操作,並且可以非常方便的支持多數據庫多租户的場景,如果併發不高,例如在開發測試環境,完全可以不依賴第三方中間件,非常容易上手部署使用。

該項目的github地址為:https://github.com/TeamStepping/Stepping.NET

Stepping

Stepping 是一個基於 BASE 的分佈式作業實現。它可以作為工作流引擎,事件收/發件箱,用於郵箱/短信發送,用於遠程接口調用等場景。

Stepping 中 Job 和  Step 是什麼?

Job 是一個分佈式事務單元,而  Step 是 job 中一個特定的任務。

一個 job(作業)包含了一個或多個 step(步驟),事務管理器會按順序執行步驟。如果步驟 1 失敗了,它將重試直到成功,然後開始執行步驟 2。

什麼場景需要 Stepping

需要執行多個步驟且確保原子性

當一個 job 開始執行,Stepping 最終會完成你佈置的所有 steps。如果你的應用在執行這些步驟期間掛了,事務管理器會在應用恢復後,繼續執行剩下的步驟。

Stepping 會按順序挨個完成你佈置的 steps。如果一個步驟失敗,它會被推遲重試,這確保了 job 的 原子性。

當你的應用在執行步驟期間掛了,Stepping 有可能已經實際完成了這個步驟,而未自知,當你的應用恢復,Stepping 會宂餘地執行這個步驟。因此,你所有的步驟都應該做到 冪等。

需要確保在 DB 事務提交後,後續步驟一定執行

當一個綁定了 DB 事務的 job 開始執行,在 DB 事務提交後,Stepping 最終會完成你佈置的所有 steps。

你無需擔心在 DB 事務提交後、後續步驟執行之前,這期間應用掛了導致的非原子性問題。我們已經使用 DTM 的 二階段消息 模式處理了這種情況。

Stepping 也支持“多租户且多數據庫”的場景,這意味着無論你的應用有多少個不同的數據庫,都不成問題。

用例

事務管理器會最終完成添加的步驟:

var job = await distributedJobFactory.CreateJobAsync();


job.AddStep(new RequestBank1TransferOutStep(args)); // 帶參數的步驟
job.AddStep<RequestBank2TransferInStep>(); // 不帶參數的步驟


await job.StartAsync();

Steps 文檔 https://github.com/TeamStepping/Stepping.NET/blob/main/docs/Steps.md 介紹瞭如何定義一個步驟。

如果你希望在 DB 事務提交後開始執行一些步驟,並且確保它們最終能夠執行成功:

var db = serviceProvider.GetRequiredService<MyDbContext>(); // 以 EF Core 舉例
await db.Database.BeginTransactionAsync();


var order = new Order(args);


db.Orders.Add(order);
await db.SaveChangesAsync();


var job = await distributedJobFactory.CreateJobAsync(new EfCoreSteppingDbContext(db));


job.AddStep(new SendOrderCreatedEmailStep(order));
job.AddStep(new SendOrderCreatedSmsStep(order));


await job.StartAsync(); // 這個方法也會提交 DB 事務

Stepping 支持 EF CoreADO.NET (即將到來),及  MongoDB

瞭解更多信息,請參閲 用法文檔: https://github.com/TeamStepping/Stepping.NET/blob/main/docs/Usage.md

安裝

請參閲 安裝文檔:https://github.com/TeamStepping/Stepping.NET/blob/main/docs/Installation.md

支持的事務管理器

Stepping 要求使用事務管理器。你可以選擇一種你喜歡的事務管理器。

Local-TM

Stepping 提供了一種簡單的內置事務管理器實現。Local-TM 與你的應用一起運行。在這種模式下,每個應用都作為自己發佈的 jobs 的事務管理器。

這種事務管理器適用於開發和測試環境,以及併發度較低的應用,不用額外維護組件

請參閲 Local-TM 文檔: https://github.com/TeamStepping/Stepping.NET/blob/main/docs/LocalTm.md

DTM Server

DTM 是一個成熟的事務管理器,並且能夠為 Stepping 提供能力。選擇 DTM ,對於併發度高的應用,性能表現更好。你也可以使用DTM的SDK,支持更多的分佈式事務模式,例如 Saga、TCC和XA。

請參閲 DTM 文檔:https://dtm.pub

聯繫我們

歡迎訪問我們的項目,並star支持我們:

https://github.com/TeamStepping/Stepping.NET

https://github.com/dtm-labs/dtm

關注【分佈式事務】公眾號,獲得更多分佈式事務相關知識