簡體   English   中英

如何使用事務/原子進行多個REST請求?

[英]How to make multiple REST requests transactional/atomic?

我有以下情況。
我有一個REST客戶端,作為其他3個REST客戶端的外觀。 (我用Java編程,使用Spring Boot)

客戶的責任之一包括對用戶進行CRUD操作。
現在,暴露自己的REST API的所有其他3個系統都有某種用戶管理。

當我收到創建用戶的請求時,我必須通過他們的REST API在這3個系統上創建它們並在我的數據庫中保留。

現在,在最好的情況下,我只需調用他們的API,將用戶插入我的數據庫中,一切都很棒。

但是,請考慮用戶創建僅在1個外部服務上成功的情況。 我是否會重試所有其他操作? 我是否嘗試刪除用戶已被取代的用戶?

這樣做的正確方法是什么?

沒有一種簡單的方法可以做到這一點。 如果“事務”的任何部分失敗,則無法可靠地回滾或重試以保證所有系統的一致性。 您需要與所有三個(四個系統)緊密集成才能使用分布式事務系統。

一種方法(假設您可以容忍節點之間的不同狀態):

  1. 假設您的外觀具有傳入的CRUD請求的持久隊列。 一旦新請求req進入隊列,您就開始要求REST客戶端執行它;
  2. 一旦所有REST客戶端執行請求並報告成功,您就可以將其從隊列中刪除,並使此更改對系統的全局狀態有效。 例如,如果req是CREATE,那么新用戶對外部世界是可見的,如果req是更新,那么更新對外部世界是可見的,依此類推。 這意味着全局狀態是門面系統數據庫中存儲的內容;
  3. 現在,如果在req正在進行時你的外觀出現故障怎么辦(並非所有REST客戶端都報告成功)? 重新啟動后,您的外觀必須從(持久)隊列中獲取所有掛起的請求,並將它們推送到REST客戶端。 這意味着REST客戶端可以檢測它們是否已經處理了該特定請求(並且它剛剛發生,Facade在它關閉之前沒有處理回復)。 通常,這是通過使用唯一請求ID(例如,UUID)來實現的。

如果您的系統只有部分REST客戶端處理請求(這意味着數據只能通過外觀訪問外部世界),則上述過程有效。 如果沒有,您需要一些支持分布式事務的系統(谷歌用於兩階段提交)。

您需要根據具體情況處理它。 在您提供的示例中,您可以嘗試刪除,但這也可能會失敗。

一旦出現故障,您需要:

  1. 處理創建用戶的重試
  2. 處理可能訪問用戶的客戶端,即使只創建了3個中的一個

對於重試 ,您可以讓啟動器重試或對請求進行排隊。

在這兩種情況下,您可能都希望設計api,以便在嘗試重新創建已創建的用戶時,它會將其視為更新。

例如,三個中只有一個成功。

啟動請求的網頁會返回錯誤。 用戶重試。 這次你更新第一個並重試創建第二個和第三個。

對於客戶查找記錄,並獲得部分用戶,你要么需要跟蹤哪些創建,或者客戶自己將只需要看到1三所創建記錄的第4個系統。 如果您的客戶總是只是一次只看三個中的一個,這甚至可能不是問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM