通過改變業務模型的預留模式避免分散式事務 - CodeOpinion
長時間執行的業務流程可能會持續幾秒鐘到幾天,您無法使用分散式事務鎖定服務中的資源。那麼有什麼選擇呢?現實世界有一個解決方案,它是一種預訂保留。
預訂模式允許您獲得有時限的有限保證,允許您與其他服務進行協調。
預訂模式一直在現實世界中使用。我們可以利用程式碼中的模式為長期執行的業務流程在服務之間提供有時限的有限保證。這是一個可以過期的有限鎖。
例如我在網上下了一個取貨訂單。該物品是為我保留的,這可以防止我去商店浪費時間並且該物品不可用。當員工從貨架上拿下物品時,該預訂有 7 天時間讓我取貨,否則該預訂將過期,其他人可以購買。
有時您只需要在現實世界(業務領域)中尋找解決方案。
預訂的一個重要方面是有時間限制。您會在電子郵件中注意到,如果我沒有在 7 天內取貨,他們將退還我的信用卡並將商品放回貨架上。
他們正在為我的物品提供鎖定/保留,該鎖定將在 7 天內到期。
當我去當地商店取貨時,這是確認我的預訂。
預訂模式
我們可以在程式碼中實現預訂模式來解決類似型別的問題。在使用者註冊的示例中,我們可以在註冊過程開始時在使用者名稱上建立預訂。一旦使用者完成使用者註冊過程,我們就可以確認預訂。
如果使用者從未完成註冊過程,則使用者名稱將在我們定義的時間後過期,讓其他人嘗試註冊相同的使用者名稱。
預訂模式有 3 個重要方面。保留、確認、到期。
為了首先在程式碼中說明這一點,我將首先展示同步版本,然後是非同步版本,這通常更適用。
使用者註冊首先檢查使用者名稱的保留是否存在。如果沒有,它將建立一個新帳戶,將其儲存到我們的資料庫中,然後告訴預訂它已完成。
public class UserRegistration { private static int _testCount = 0; private readonly UsernameReservationSync _reservation; private readonly IUserRepository _repository; public UserRegistration(UsernameReservationSync reservation, IUserRepository repository) { _reservation = reservation; _repository = repository; } public bool Register(string username) { if (_reservation.Reserve(username) == false) { return false; } // For testing to show the expiry if (username == "test" && _testCount == 0) { _testCount++; return false; } var account = new Account(username); _repository.Add(account); _repository.Save(); if (_reservation.Complete(username) == false) { _repository.Remove(account); return false; } return true; } |
預留本身具有預留、完成的能力。在內部 5 秒後,如果仍然保留,它將使使用者名稱過期。這是一個示例,沒有使用真實的資料庫,也沒有像在真實的生產環境中那樣處理併發。
public class UsernameReservationSync { private TimeSpan Timeout => TimeSpan.FromSeconds(5); private readonly FakeDatabase _db; public UsernameReservationSync(FakeDatabase db) { _db = db; } public bool Reserve(string username) { if (_db.RegisteredUsernames.Any(x => x == username)) { return false; } if (_db.ReservedUsernames.Any(x => x == username)) { return false; } _db.ReservedUsernames.Add(username); Task.Run(async () => { await Task.Delay(Timeout); Expire(username); }); return true; } private void Expire(string username) { _db.ReservedUsernames.Remove(username); } public bool Complete(string username) { if (_db.ReservedUsernames.Any(x => x == username) == false) { return false; } if (_db.RegisteredUsernames.Any(x => x == username)) { return false; } _db.ReservedUsernames.Remove(username); _db.RegisteredUsernames.Add(username); return true; } } |
詳細點選標題
相關文章
- 事務使用中如何避免誤用分散式事務分散式
- 分散式事務Saga模式分散式模式
- 分散式事務之Seata的AT模型分散式模型
- 分散式事務(一)—分散式事務的概念分散式
- 微服務的分散式事務模式比較 | RedHat微服務分散式模式Redhat
- 比較微服務中的分散式事務模式微服務分散式模式
- 分散式事務 | 使用DTM 的Saga 模式分散式模式
- 分散式事務框架 seata-golang 通訊模型詳解分散式框架Golang模型
- seata分散式事務AT模式介紹(二)分散式模式
- 分散式事務(3)---RocketMQ實現分散式事務原理分散式MQ
- 分散式事務解決方案——柔性事務與服務模式分散式模式
- php基於dtm分散式事務管理器實現tcc模式分散式事務demoPHP分散式模式
- 微服務痛點-基於Dubbo + Seata的分散式事務(AT)模式微服務分散式模式
- 本地事務和分散式事務的區別分散式
- 分散式事務(4)---RocketMQ實現分散式事務專案分散式MQ
- 分散式事務之事務實現模式與技術(四)分散式模式
- TX-LCN分散式事務之LCN模式分散式模式
- 分散式事務鎖模式之一:租用Lease分散式模式
- 分散式事務和分散式hash分散式
- 微服務痛點-基於Dubbo + Seata的分散式事務(TCC模式)微服務分散式模式
- seata 分散式事務分散式
- 聊聊分散式事務分散式
- 理解分散式事務分散式
- 分散式事務概述分散式
- 分散式事務之Spring事務與JMS事務(二)分散式Spring
- 分散式事務~從seata例項來學習分散式事務分散式
- DAOS 分散式非同步物件儲存|事務模型分散式非同步物件模型
- 微服務架構 | 11.1 整合 Seata AT 模式實現分散式事務微服務架構模式分散式
- PHP 微服務之 [分散式事務]PHP微服務分散式
- PHP 微服務之【分散式事務】PHP微服務分散式
- Seata 分散式事務框架 TCC 模式原始碼分析分散式框架模式原始碼
- Seata分散式事務TA模式原始碼解讀分散式模式原始碼
- 分散式系統(三)——分散式事務分散式
- 通過Dapr實現一個簡單的基於.net的微服務電商系統(十九)——分散式事務之Saga模式微服務分散式模式
- 分散式事務利器——RocketMQ事務訊息的啟示分散式MQ
- 分散式事務實戰分散式
- SpringCloud(六)分散式事務SpringGCCloud分散式
- 分散式事務總結分散式