簡體   English   中英

如何在Redis中實現回滾事務

[英]How to implement transaction with rollback in Redis

我的程序需要將數據作為事務添加到Redis中的兩個列表中。 兩個列表中的數據應保持一致。 如果存在異常或系統故障,因此程序僅將數據添加到一個列表,則系統應該能夠恢復和回滾。 但是基於Redis doc,它不支持回滾。 我該如何實現呢? 我使用的語言是Java。

如果您需要事務回滾,我建議使用Redis之外的其他東西。 Redis事務與其他數據存儲不同。 甚至Multi / Exec也無法滿足您的需求 - 首先是因為沒有回滾。 如果你想要回滾,你必須下拉兩個列表,以便你可以恢復 - 並希望在我們的錯誤條件和“回滾”之間沒有其他客戶端也修改了任何一個列表。 以理智和可靠的方式做到這一點並非易事,也不簡單。 它也可能不是一個很好的問題,因為它會非常廣泛,而不是Redis具體。

現在,為什么EXEC不做人們想象的事情。 在您建議的場景中,MULTI / EXEC 處理以下情況:

  1. 您設置了WATCHes以確保沒有發生其他更改
  2. 您的客戶在發出EXEC之前就已經死亡
  3. Redis內存不足

由於發出EXEC命令,完全有可能出錯。 當您發出EXEC時,Redis將執行隊列中的所有命令並返回錯誤列表。 它不會提供add-to-list-1工作和add-to-list-2失敗的情況。 你仍然會讓你的兩個列表不同步。 當您發出,說多發行后LPUSH,你總是會得到回一個OK ,除非你:

  • a)之前添加的手表和該列表中的某些內容已更改或
  • b)Redis返回OOM條件以響應排隊的push命令

DISCARD不像有些人想象的那樣有效。 使用DISCARD 代替 EXEC,而不是作為回滾機制。 一旦您發出EXEC,您的交易就完成了。 Redis根本沒有任何回滾機制 - 這不是Redis的交易所涉及的。

理解Redis調用事務的關鍵是要意識到它們本質上是客戶端連接級別的命令隊列。 它們不是數據庫狀態機。

Redis交易是不同的。 它保證了兩件事。

  1. 執行所有命令或不執行任何命令
  2. 順序和不間斷的命令

話雖如此,如果您可以控制代碼並知道何時會發生系統故障(某種程度上捕獲異常),您就可以通過這種方式實現您的需求。

  1. MULTI - >啟動交易
  2. LPUSH queue1 1 - >推入隊列1
  3. LPUSH queue2 1 - >推入隊列2
  4. EXEC /放棄

在第4步中,如果沒有錯誤,請執行EXEC,如果遇到錯誤或異常,並且想要回滾,請執行DISCARD。

希望它有意義。

暫無
暫無

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

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