一、概述:
和眾多其它數(shù)據(jù)庫一樣,Redis作為NoSQL數(shù)據(jù)庫也同樣提供了事務機制。在Redis中,MULTI/EXEC/DISCARD/WATCH這四個命令是我們實現(xiàn)事務的基石。相信對有關系型數(shù)據(jù)庫開發(fā)經(jīng)驗的開發(fā)者而言這一概念并不陌生,即便如此,我們還是會簡要的列出Redis中事務的實現(xiàn)特征:
1). 在事務中的所有命令都將會被串行化的順序執(zhí)行,事務執(zhí)行期間,Redis不會再為其它客戶端的請求提供任何服務,從而保證了事物中的所有命令被原子的執(zhí)行。
2). 和關系型數(shù)據(jù)庫中的事務相比,在Redis事務中如果有某一條命令執(zhí)行失敗,其后的命令仍然會被繼續(xù)執(zhí)行。
3). 我們可以通過MULTI命令開啟一個事務,有關系型數(shù)據(jù)庫開發(fā)經(jīng)驗的人可以將其理解為"BEGIN TRANSACTION"語句。在該語句之后執(zhí)行的命令都將被視為事務之內的操作,最后我們可以通過執(zhí)行EXEC/DISCARD命令來提交/回滾該事務內的所有操作。這兩個Redis命令可被視為等同于關系型數(shù)據(jù)庫中的COMMIT/ROLLBACK語句。
4). 在事務開啟之前,如果客戶端與服務器之間出現(xiàn)通訊故障并導致網(wǎng)絡斷開,其后所有待執(zhí)行的語句都將不會被服務器執(zhí)行。然而如果網(wǎng)絡中斷事件是發(fā)生在客戶端執(zhí)行EXEC命令之后,那么該事務中的所有命令都會被服務器執(zhí)行。
5). 當使用Append-Only模式時,Redis會通過調用系統(tǒng)函數(shù)write將該事務內的所有寫操作在本次調用中全部寫入磁盤。然而如果在寫入的過程中出現(xiàn)系統(tǒng)崩潰,如電源故障導致的宕機,那么此時也許只有部分數(shù)據(jù)被寫入到磁盤,而另外一部分數(shù)據(jù)卻已經(jīng)丟失。Redis服務器會在重新啟動時執(zhí)行一系列必要的一致性檢測,一旦發(fā)現(xiàn)類似問題,就會立即退出并給出相應的錯誤提示。此時,我們就要充分利用Redis工具包中提供的redis-check-aof工具,該工具可以幫助我們定位到數(shù)據(jù)不一致的錯誤,并將已經(jīng)寫入的部分數(shù)據(jù)進行回滾。修復之后我們就可以再次重新啟動Redis服務器了。
二、相關命令列表:
命令原型 | 時間復雜度 | 命令描述 | 返回值 |
MULTI | 用于標記事務的開始,其后執(zhí)行的命令都將被存入命令隊列,直到執(zhí)行EXEC時,這些命令才會被原子的執(zhí)行。 | 始終返回OK | |
EXEC | 執(zhí)行在一個事務內命令隊列中的所有命令,同時將當前連接的狀態(tài)恢復為正常狀態(tài),即非事務狀態(tài)。如果在事務中執(zhí)行了WATCH命令,那么只有當WATCH所監(jiān)控的Keys沒有被修改的前提下,EXEC命令才能執(zhí)行事務隊列中的所有命令,否則EXEC將放棄當前事務中的所有命令。 | 原子性的返回事務中各條命令的返回結果。如果在事務中使用了WATCH,一旦事務被放棄,EXEC將返回NULL-multi-bulk回復。 | |
DISCARD | 回滾事務隊列中的所有命令,同時再將當前連接的狀態(tài)恢復為正常狀態(tài),即非事務狀態(tài)。如果WATCH命令被使用,該命令將UNWATCH所有的Keys。 | 始終返回OK。 | |
WATCHkey [key ...] | O(1) | 在MULTI命令執(zhí)行之前,可以指定待監(jiān)控的Keys,然而在執(zhí)行EXEC之前,如果被監(jiān)控的Keys發(fā)生修改,EXEC將放棄執(zhí)行該事務隊列中的所有命令。 | 始終返回OK。 |
UNWATCH | O(1) | 取消當前事務中指定監(jiān)控的Keys,如果執(zhí)行了EXEC或DISCARD命令,則無需再手工執(zhí)行該命令了,因為在此之后,事務中所有被監(jiān)控的Keys都將自動取消。 | 始終返回OK。 |
三、命令示例:
1. 事務被正常執(zhí)行:
在Redis的事務中,WATCH命令可用于提供CAS(check-and-set)功能。假設我們通過WATCH命令在事務執(zhí)行之前監(jiān)控了多個Keys,倘若在WATCH之后有任何Key的值發(fā)生了變化,EXEC命令執(zhí)行的事務都將被放棄,同時返回Null multi-bulk應答以通知調用者事務執(zhí)行失敗。例如,我們再次假設Redis中并未提供incr命令來完成鍵值的原子性遞增,如果要實現(xiàn)該功能,我們只能自行編寫相應的代碼。其偽碼如下:
|
新聞熱點
疑難解答
圖片精選