簡體   English   中英

redis - 如何創建交易

[英]redis - how to create a transation

背景

我需要一種在 REDIS 中創建事務的方法,如果一個命令失敗,我需要整個事務失敗/回滾。

我之前試過問過一次( 如果其中一個命令不起作用,REDIS-管道不會失敗

但也許我沒有問清楚,或者我的問題措辭中有什么地方丟失了。 或者我不明白答案。 但無論如何,我一直在做更多的研究,似乎 REDIS 確實通過 MULTI 和 EXEC 命令進行了交易。 在我的例子中,因為我使用的是 pyredis,所以我可以創建一個將參數“transaction”設置為 True 的管道。

代碼

為了更好地理解事務和管道的工作原理,我編寫了代碼來“模擬”失敗,以證明我的事務中的命令正在回滾。 這就是我的 flask 應用程序中的內容:

@application.route("/test/transactions/<int:trigger>")
def test_transactions(trigger):
    try:
        logging.info('test transactions triggered')
        r = redis.Redis(connection_pool=POOL)
        p = r.pipeline(transaction=True)
        p.hmset('multitest', {'thefield':'thevalue'})
        if trigger==1:  
            assert 1==0, "trigger enabled. this will cause failure."
        p.hmset('multitest2', {'a':'b'})
        retval = p.execute()
        logging.info(retval)
        return "keys created"
    except Exception as e:
        logging.error(e)
        return "keys not created"

當我傳入 0 作為觸發器時,它不會“失敗”,因此系統會創建兩個哈希值。 當我設置觸發器時,它似乎表現正確,因為我在數據庫中沒有任何哈希值。

問題

  1. 這是一個很好的測試嗎? 已經證明交易有效? 如果沒有,你能建議一個更好的測試嗎?

  2. 在我的真實代碼中,我計划檢查 retval 的內容(順便說一下,它看起來像這樣:[0,0] 如果什么都沒做,或者 [1, 1] 如果我確實添加/刪除了一些東西.) 如果我期待 [1,1] 並且我得到不同的東西,我將假設交易失敗並且該方法只返回 false。 有一個更好的方法嗎?

預先感謝您的時間和意見。

Redis的事務不具有“回滾”功能-調用p.execute()后,將執行其中的操作。 您可以在執行之前的任何時間通過調用p.discard()取消事務。

丟棄事務時,它不會回滾,因為實際上沒有執行任何操作。

@application.route("/test/transactions/<int:trigger>")
def test_transactions(trigger):
    try:
        logging.info('test transactions triggered')
        r = redis.Redis(connection_pool=POOL)
        p = r.pipeline(transaction=True)
        p.hmset('multitest', {'thefield':'thevalue'})
        if trigger==1:  
            p.discard()
            return "discarded"
        else:
            p.hmset('multitest2', {'a':'b'})
            retval = p.execute()
            logging.info(retval)
            return "keys created"
    except Exception as e:
        logging.error(e)

注意:我的代碼還不完整-您可以先檢查trigger然后跳過嘗試進行交易的過程。

我在 redis-py 中使用事務/管道時遇到相同或類似的問題。 我認為您的示例涵蓋了由於您的代碼中的某些異常而導致的失敗,但不包括您與 redis 的交互中的錯誤。我自己還沒有對此進行測試,但這是我閱讀 redis 有關交易的文檔 [1] 的結果:

事務期間可能發生兩種錯誤:無法對命令進行排隊,或在 EXEC 之后失敗。 對於第一類錯誤,事務可以中止。 第二種不能,也不能回滾。 然而,第二種情況只會發生在排隊時未檢測到的語法錯誤或持有錯誤數據類型的鍵上。 這些是編程錯誤,爭論是不應該實施回滾來防止這些錯誤。

在排隊失敗時,可以通過調用 DISCARD 顯式中止事務(我認為這不會在 redis-py 中工作,因為這只會緩沖命令 [2]),或者它將與對 EXEC 的失敗調用一起隱式完成(假設 redis 版本 >= 2.6.5)。

參考:

[1] Redis 交易: https://redis.io/topics/transactions

[2] redis-py,管道事務(見_execute_transaction): https://redis.readthedocs.io/en/stable/_modules/redis/client.html

暫無
暫無

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

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