1. 程式人生 > >Redis學習手冊(事務)

Redis學習手冊(事務)

一、概述:

      和眾多其它資料庫一樣,Redis作為NoSQL資料庫也同樣提供了事務機制。在Redis中,MULTI/EXEC/DISCARD/WATCH這四個命令是我們實現事務的基石。相信對有關係型資料庫開發經驗的開發者而言這一概念並不陌生,即便如此,我們還是會簡要的列出Redis中事務的實現特徵:
      1). 在事務中的所有命令都將會被序列化的順序執行,事務執行期間,Redis不會再為其它客戶端的請求提供任何服務,從而保證了事物中的所有命令被原子的執行。
      2). 和關係型資料庫中的事務相比,在Redis事務中如果有某一條命令執行失敗,其後的命令仍然會被繼續執行。
      3). 我們可以通過MULTI命令開啟一個事務,有關係型資料庫開發經驗的人可以將其理解為"BEGIN TRANSACTION"語句。在該語句之後執行的命令都將被視為事務之內的操作,最後我們可以通過執行EXEC/DISCARD命令來提交/回滾該事務內的所有操作。這兩個Redis命令可被視為等同於關係型資料庫中的COMMIT/ROLLBACK語句。
      4). 在事務開啟之前,如果客戶端與伺服器之間出現通訊故障並導致網路斷開,其後所有待執行的語句都將不會被伺服器執行。然而如果網路中斷事件是發生在客戶端執行EXEC命令之後,那麼該事務中的所有命令都會被伺服器執行。
      5). 當使用Append-Only模式時,Redis會通過呼叫系統函式write將該事務內的所有寫操作在本次呼叫中全部寫入磁碟。然而如果在寫入的過程中出現系統崩潰,如電源故障導致的宕機,那麼此時也許只有部分資料被寫入到磁碟,而另外一部分資料卻已經丟失。Redis伺服器會在重新啟動時執行一系列必要的一致性檢測,一旦發現類似問題,就會立即退出並給出相應的錯誤提示。此時,我們就要充分利用Redis工具包中提供的redis-check-aof工具,該工具可以幫助我們定位到資料不一致的錯誤,並將已經寫入的部分資料進行回滾。修復之後我們就可以再次重新啟動Redis伺服器了。

二、相關命令列表:

命令原型 時間複雜度 命令描述 返回值
MULTI 用於標記事務的開始,其後執行的命令都將被存入命令佇列,直到執行EXEC時,這些命令才會被原子的執行。 始終返回OK
EXEC 執行在一個事務內命令佇列中的所有命令,同時將當前連線的狀態恢復為正常狀態,即非事務狀態。如果在事務中執行了WATCH命令,那麼只有當WATCH所監控的Keys沒有被修改的前提下,EXEC命令才能執行事務佇列中的所有命令,否則EXEC將放棄當前事務中的所有命令。 原子性的返回事務中各條命令的返回結果。如果在事務中使用了WATCH,一旦事務被放棄,EXEC將返回NULL-multi-bulk回覆。
DISCARD
回滾事務佇列中的所有命令,同時再將當前連線的狀態恢復為正常狀態,即非事務狀態。如果WATCH命令被使用,該命令將UNWATCH所有的Keys。 始終返回OK。
WATCHkey [key ...] O(1) 在MULTI命令執行之前,可以指定待監控的Keys,然而在執行EXEC之前,如果被監控的Keys發生修改,EXEC將放棄執行該事務佇列中的所有命令。 始終返回OK。
UNWATCH O(1) 取消當前事務中指定監控的Keys,如果執行了EXEC或DISCARD命令,則無需再手工執行該命令了,因為在此之後,事務中所有被監控的Keys都將自動取消。 始終返回OK。

三、命令示例:

   1. 事務被正常執行:


    #在Shell命令列下執行Redis的客戶端工具。
    /> redis-cli
    #在當前連線上啟動一個新的事務。

    redis 127.0.0.1:6379> multi
    OK
    #執行事務中的第一條命令,從該命令的返回結果可以看出,該命令並沒有立即執行,而是存於事務的命令佇列。
    redis 127.0.0.1:6379> incr t1
    QUEUED
    #又執行一個新的命令,從結果可以看出,該命令也被存於事務的命令佇列。
    redis 127.0.0.1:6379> incr t2
    QUEUED
    #執行事務命令佇列中的所有命令,從結果可以看出,佇列中命令的結果得到返回。
    redis 127.0.0.1:6379> exec
    1) (integer) 1
    2) (integer) 1
        
   2. 事務中存在失敗的命令:
    #開啟一個新的事務。
    redis 127.0.0.1:6379> multi
    OK
    #設定鍵a的值為string型別的3。
    redis 127.0.0.1:6379> set a 3
    QUEUED
    #從鍵a所關聯的值的頭部彈出元素,由於該值是字串型別,而lpop命令僅能用於List型別,因此在執行exec命令時,該命令將會失敗。
    redis 127.0.0.1:6379> lpop a
    QUEUED
    #再次設定鍵a的值為字串4。
    redis 127.0.0.1:6379> set a 4
    QUEUED
    #獲取鍵a的值,以便確認該值是否被事務中的第二個set命令設定成功。
    redis 127.0.0.1:6379> get a
    QUEUED
    #從結果中可以看出,事務中的第二條命令lpop執行失敗,而其後的set和get命令均執行成功,這一點是Redis的事務與關係型資料庫中的事務之間最為重要的差別。
    redis 127.0.0.1:6379> exec
    1) OK
    2) (error) ERR Operation against a key holding the wrong kind of value
    3) OK
    4) "4"

   3. 回滾事務:
    #為鍵t2設定一個事務執行前的值。
    redis 127.0.0.1:6379> set t2 tt
    OK
    #開啟一個事務。
    redis 127.0.0.1:6379> multi
    OK
    #在事務內為該鍵設定一個新值。
    redis 127.0.0.1:6379> set t2 ttnew
    QUEUED
    #放棄事務。
    redis 127.0.0.1:6379> discard
    OK
    #檢視鍵t2的值,從結果中可以看出該鍵的值仍為事務開始之前的值。
    redis 127.0.0.1:6379> get t2
    "tt"

四、WATCH命令和基於CAS的樂觀鎖:

      在Redis的事務中,WATCH命令可用於提供CAS(check-and-set)功能。假設我們通過WATCH命令在事務執行之前監控了多個Keys,倘若在WATCH之後有任何Key的值發生了變化,EXEC命令執行的事務都將被放棄,同時返回Null multi-bulk應答以通知呼叫者事務執行失敗。例如,我們再次假設Redis中並未提供incr命令來完成鍵值的原子性遞增,如果要實現該功能,我們只能自行編寫相應的程式碼。其偽碼如下:
      val = GET mykey
      val = val + 1
      SET mykey $val
      以上程式碼只有在單連線的情況下才可以保證執行結果是正確的,因為如果在同一時刻有多個客戶端在同時執行該段程式碼,那麼就會出現多執行緒程式中經常出現的一種錯誤場景--競態爭用(race condition)。比如,客戶端A和B都在同一時刻讀取了mykey的原有值,假設該值為10,此後兩個客戶端又均將該值加一後set回Redis伺服器,這樣就會導致mykey的結果為11,而不是我們認為的12。為了解決類似的問題,我們需要藉助WATCH命令的幫助,見如下程式碼:
      WATCH mykey
      val = GET mykey
      val = val + 1
      MULTI
      SET mykey $val
      EXEC
      和此前程式碼不同的是,新程式碼在獲取mykey的值之前先通過WATCH命令監控了該鍵,此後又將set命令包圍在事務中,這樣就可以有效的保證每個連線在執行EXEC之前,如果當前連接獲取的mykey的值被其它連線的客戶端修改,那麼當前連線的EXEC命令將執行失敗。這樣呼叫者在判斷返回值後就可以獲悉val是否被重新設定成功。

相關推薦

Redis學習手冊(事務)

一、概述:       和眾多其它資料庫一樣,Redis作為NoSQL資料庫也同樣提供了事務機制。在Redis中,MULTI/EXEC/DISCARD/WATCH這四個命令是我們實現事務的基石。相信對有關係型資料庫開發經驗的開發者而言這一概念並不陌生,即便如此,我們還是會

redis 學習手冊事務 transaction 操作

事務操作 概述 Redis事務讓一組命令在單個步驟中執行。 事務中有兩個屬性,這說明如下: 在一個事務中所有命令按順序執行,作為一個單一獨立的操作。 Redis事務也是原子的。原子就意味著要麼所有命令都執行,要麼都不進行處理。 但是Redis的Transactions

redis學習教程三《發送訂閱、事務、連接》

微軟雅黑 pin 發布者 tail 順序 mil visitor 模式 b- redis學習教程三《發送訂閱、事務、連接》 一:發送訂閱 Redis發布訂閱(pub/sub)是一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息。Redis 發

分布式緩存技術redis學習系列(三)——redis高級應用(主從、事務與鎖、持久化)

master ica not ood www working can 出了 owin 上文《詳細講解redis數據結構(內存模型)以及常用命令》介紹了redis的數據類型以及常用命令,本文我們來學習下redis的一些高級特性。 回到頂部 安全性設置 設置客戶端操作秘密

Redis學習筆記06Redis命令之(5)事務

mman 客戶 cau 連接 discard 順序 strong 存在 執行命令 1.1.1. multi 開始一個新事務。 redis.coe2coe.me:6379> multi OK 執行此命令後,後面執行的set等命令將被緩存,直到被discard

Redis 學習之路 (010) - redis命令手冊

哈希 sts 集中 cluster htm second 不同 index scribe Redis 鍵(key) 命令 命令描述 Redis DEL 命令 該命令用於在 key 存在是刪除 key。 Redis Dump 命令 序列化給定 key ,並返回被

StackExchange.Redis學習筆記(四) 事務控制和Batch批量操作

成了 pan arp 展示 關於 public 連續 因此 用戶 Redis事物 Redis命令實現事務 Redis的事物包含在multi和exec(執行)或者discard(回滾)命令中 和sql事務不同的是,Redis調用Exec只是將所有的命令變成一個單元一起執行,期

redis學習-事務命令

我們 遇到 exe 取消 bubuko 執行 如果 image card multi:開啟事務 exec:提交事務 discard:取消事務 1.開啟事務之後,每次執行命令之後,都要先進入事務隊列中,只有在執行 exec之後才開始執行 2.開啟事務之後,每次執行命令之後,

redis學習(四)redis事務

redis事務 1.redis事務介紹   redis的事務可以理解為一系列序列命令的集合。redis的事務和單條命令一樣,都是redis的最小執行單位,因此一個事務內的命令,要麼全部執行,要麼全部不執行。事務的概念對於熟悉資料庫的人們並不陌生,而redis作為一個數據庫系統,必然會對事務進行一定的支援。

Redis學習記錄(九)------Redis 事務

Redis 事務 Redis 事務可以一次執行多個命令, 並且帶有以下兩個重要的保證: 批量操作在傳送 EXEC 命令前被放入佇列快取。 收到 EXEC 命令後進入事務執行,事務中任意命令執行失敗,其餘的命令依然被執行。 在事務執行過程,其他客戶端提交的命令請求不會插

Redis學習八:Redis事務

一、是什麼 可以一次執行多個命令,本質是一組命令的集合。一個事務中的所有命令都會序列化,按順序地序列化執行而不會被其它命令插入,不許加塞。 二、能幹嘛  一個佇列中,一次性、順序性、排他性的執行一系列命令 三、怎麼玩 1.常用命令 2.Case1:正常執行 3.Case2:放棄事

Redis學習筆記~Redis事務機制與Lind.DDD.Repositories.Redis事務機制的實現

回到目錄 Redis本身支援事務,這就是SQL資料庫有Transaction一樣,而Redis的驅動也支援事務,這在ServiceStack.Redis就有所體現,它也是目前最受業界認可的Redis驅動,而它將Redis的事務機制(MULTI,Exec,Watch等)封裝成了比較友好的實現方式,如下面的程

Redis學習——Redis事務

Redis和傳統的關係型資料庫一樣,因為具有持久化的功能,所以也有事務的功能! 有關事務相關的概念和介紹,這裡就不做介紹。 在學習Redis的事務之前,首先丟擲一個面試的問題。 面試官:請問Redis支援事務嗎?如果支援和傳統的關係型資料的事務有什麼

redis學習(五) redis進階之事務和過期時間的應用

事務redis中的事務是一組命令的集合。使得一個事務中的redis命令要麼全執行,要麼全不執行使用方式: multi 和exec完成multi: 告訴redis將同一個事務的命令儲存起來。  之後傳送兩個SADD, redis返回queued表示命令進入了等待執行的事務佇列中

Redis學習筆記~Twenproxy所起到的作用

out arm mdb ntp ddd pin alq odi mib 回到目錄 Twenproxy除了可以作為redis的代理,它同樣支持memerycached。我這裏主要了解Twemproxy在redis集群上的解決方案。Twemproxy除了完美的解決了分片,路由

redis學習教程一《Redis的安裝和配置》

遠程服務 name 工具 列表 端口號 裏的 redis服務器 映射 tin redis學習教程一《Redis的安裝和配置》 Redis的優點 以下是Redis的一些優點。 異常快 - Redis非常快,每秒可執行大約110000次的設置(SET)操作,每秒大約可執

redis學習教程五《管道、分區》

平衡 集合 過程 含義 local 方式 持久性 class 鍵值 redis學習教程五《管道、分區》 一:管道 Redis是一個TCP服務器,支持請求/響應協議。 在Redis中,請求通過以下步驟完成: 客戶端向服務器發送查詢,並從套接字讀取,通常以阻塞的方式,用

redis學習教程四《管理、備份、客戶端連接》

node 讀文件 配置文件 cluster config 方案 then connect ram redis學習教程四《管理、備份、客戶端連接》 一:Redis服務器命令 Redis服務器命令 下表列出了與Redis服務器相關的一些基本命令。 序號命令說明

Redis學習筆記3-Redis5個可運行程序命令的使用

運行程序 檢查 mil 數據文件 img usr pre text mod 在redis安裝文章中,說到安裝好redis後,在/usr/local/bin下有5個關於redis的可運行程序。以下關於這5個可運行程序命令的具體說明。 redis-server Redi

Python學習手冊筆記(1):Python對象類型

python 在Python中一切皆對象,Python程序可以分解為模塊、語句、表達式及對象。如下所示:1 程序由模塊組成2 模塊包含語句3 語句包含表達式4 表達式建立並處理對象 內置對象(核心類型):1)數字:>>> 2+2 #整數加法4>>&g