??前言
Redis事務是一個組有多個Redis命令的集合,這些命令可以作為一個原子操作來執(zhí)行。
Redis事務通常用于以下兩種情況:
-
保證操作的原子性:在多個命令的執(zhí)行過程中,如果有一個命令執(zhí)行失敗,整個事務都需要回滾(撤銷)到事務開始前的狀態(tài),確保數(shù)據(jù)的一致性。
-
實現(xiàn)樂觀鎖:通過在事務中監(jiān)視某些鍵,如果這些鍵在事務執(zhí)行之前被其他客戶端修改,則事務可以取消執(zhí)行,從而避免了出現(xiàn)死鎖或數(shù)據(jù)不一致的情況。
在Redis中,通過使用MULTI命令開始一個事務,然后將多個命令添加到事務中,最后使用EXEC命令來執(zhí)行這些命令。如果事務中的任何一個命令執(zhí)行失敗,可以使用DISCARD命令來取消事務,或者使用UNWATCH命令來取消對鍵的監(jiān)視。
Redis的與事務相關的命令說明:
- DISCARD:用于取消一個事務,放棄事務中所有未執(zhí)行的命令,并恢復到事務開始前的狀態(tài)。
- EXEC:用于執(zhí)行一個事務,將所有已組裝但未執(zhí)行的命令一次性執(zhí)行,并返回執(zhí)行結果。
- MULTI:用于組裝一個事務,將多個命令放入事務中,等待后續(xù)的EXEC命令來執(zhí)行這些命令。
- UNWATCH:用于取消對所有鍵的監(jiān)視,這個命令通常在使用WATCH命令監(jiān)視一些鍵時使用,以確保在執(zhí)行事務之前,這些鍵沒有被其他客戶端修改。
- WATCH:用于監(jiān)視一些鍵,一旦這些鍵在事務執(zhí)行之前被改變,則取消事務的執(zhí)行。這個命令通常與MULTI命令一起使用,用于實現(xiàn)類似于"樂觀鎖"的效果。
這些命令通常用于保證在Redis事務中的操作的原子性和一致性。通過將多個命令放入同一個事務中,可以確保這些命令作為一個整體一起執(zhí)行,并且在有其他客戶端對被監(jiān)視的鍵進行修改時,能夠適當?shù)靥幚頉_突和錯誤。
Redis 事務可以一次執(zhí)行多個命令, 并且?guī)в幸韵氯齻€重要的保證:
- 批量操作在發(fā)送 EXEC 命令前被放入隊列緩存。
- 收到 EXEC 命令后進入事務執(zhí)行,事務中任意命令執(zhí)行失敗,其余的命令依然被執(zhí)行。
- 在事務執(zhí)行過程,其他客戶端提交的命令請求不會插入到事務執(zhí)行命令序列中。
一個事務從開始到執(zhí)行會經(jīng)歷以下三個階段:
- 開始事務。
- 命令入隊。
- 執(zhí)行事務。
??DISCARD(取消事務,放棄執(zhí)行事務塊內的所有命令)
說明:
- DISCARD命令是Redis事務的一部分,用于取消當前事務,恢復到事務開始前的狀態(tài)。
- 使用DISCARD命令可以在事務執(zhí)行過程中取消事務,并且不會對已有的鍵值產(chǎn)生影響。
時間復雜度:
- O(1)。
返回值:文章來源:http://www.zghlxwxcb.cn/news/detail-541477.html
- 總是返回?OK?
以下是一個使用DISCARD命令的示例代碼:
127.0.0.1:6379> multi # 開始一個事務
OK
127.0.0.1:6379> set key1 "value1" # 添加一個SET命令到事務中
QUEUED
127.0.0.1:6379> set key2 "value2" # 添加另一個SET命令到事務中
QUEUED
127.0.0.1:6379> discard # 取消事務,不執(zhí)行SET命令
OK
- 在這個示例中,通過使用DISCARD命令,第一個SET和第二個SET命令不會生效,并且整個事務都被取消了。
- 單個 Redis 命令的執(zhí)行是原子性的,但 Redis 沒有在事務上增加任何維持原子性的機制,所以 Redis 事務的執(zhí)行并不是原子性的。
- 事務可以理解為一個打包的批量執(zhí)行腳本,但批量指令并非原子化的操作,中間某條指令的失敗不會導致前面已做指令的回滾,也不會造成后續(xù)的指令不做。
??EXEC(執(zhí)行所有事務塊內的命令)
說明:
- EXEC命令是Redis事務的一部分,用于執(zhí)行事務中所有添加的命令。
- 當使用EXEC命令時,事務中的所有命令將作為一個原子操作被執(zhí)行,如果有一個命令執(zhí)行失敗,整個事務將回滾到開始前的狀態(tài)。
- 舉例:假如某個(某些) key 正處于 WATCH 命令的監(jiān)視之下,且事務塊中有和這個(或這些) key 相關的命令,那么 EXEC 命令只在這個(或這些) key 沒有被其他命令所改動的情況下執(zhí)行并生效,否則該事務被打斷終止。
時間復雜度:
- 事務塊內所有命令的時間復雜度的總和。
返回值:
- 事務塊內所有命令的返回值,按命令執(zhí)行的先后順序排列。
- 當操作被打斷時,返回空值?nil?。
以下是一個使用EXEC命令的示例代碼:
# 事務被成功執(zhí)行
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR userid
QUEUED
127.0.0.1:6379> INCR userid
QUEUED
127.0.0.1:6379> INCR userid
QUEUED
redis> PING
QUEUED
redis> EXEC
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG
# 監(jiān)視 key ,且事務成功執(zhí)行
127.0.0.1:6379> WATCH lock lock_value
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET lock "xiaojian"
QUEUED
127.0.0.1:6379> INCR lock_value
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (integer) 1
# 監(jiān)視 key ,且事務被打斷
127.0.0.1:6379> WATCH lock lock_value # 監(jiān)視lock鍵 和 lock_value鍵
OK
127.0.0.1:6379> MULTI # 開始一個事務
OK
127.0.0.1:6379> SET lock "mr" # 就在這時,另一個客戶端修改了 lock 鍵的值,另一個客戶端修改 這個被監(jiān)視的 lock鍵,此時事務必定是失敗的!
QUEUED
127.0.0.1:6379> SET lock_value # 此時就算 lock_value 沒被修改,事務失敗已成定局。
QUEUED
127.0.0.1:6379> EXEC # 因為 lock 被其他客戶端修改,事務自動取消執(zhí)行。
(nil)
??MULTI(標記一個事務塊的開始)
說明:
- MULTI命令是Redis事務的一部分,用于開始一個新事務,并將后續(xù)的命令添加到這個事務中,直到使用EXEC命令執(zhí)行這些命令為止。
- 事務塊內的多條命令會按照先后順序被放進一個隊列當中,最后由 EXEC 命令原子性(atomic)地執(zhí)行。
- 使用MULTI命令可以將多個命令添加到事務中,并且可以在需要時使用DISCARD命令取消事務,或者使用EXEC命令執(zhí)行事務中的所有命令。
時間復雜度:
- O(1)。
返回值:
- 返回 OK 。
以下是一個使用MULTI命令的示例代碼:
127.0.0.1:6379> multi # 標記事務開始
OK
127.0.0.1:6379> set key1 value1 # 多條命令按順序入隊
QUEUED
127.0.0.1:6379> set key2 valus2
QUEUED
127.0.0.1:6379> exec # 執(zhí)行
1) OK
2) OK
- 在這個示例中,通過使用MULTI命令,將兩個SET命令添加到事務中,使用EXEC命令執(zhí)行事務中的所有命令?;蛘呖梢允褂肈ISCARD命令取消事務,這樣兩個SET命令都不會被執(zhí)行。
- MULTI命令是Redis事務的一個重要組成部分,用于開始一個新事務并將后續(xù)的命令添加到這個事務中。
??UNWATCH(取消 WATCH 命令對所有 key 的監(jiān)視)
說明:
- UNWATCH命令是Redis事務的一部分,用于取消對所有鍵的監(jiān)視,這個命令通常在使用WATCH命令監(jiān)視一些鍵時使用,以確保在執(zhí)行事務之前,這些鍵沒有被其他客戶端修改。
- 當使用UNWATCH命令時,Redis將取消對所有鍵的監(jiān)視,如果有其他客戶端在這些鍵上執(zhí)行了修改操作,也不會影響當前客戶端的事務執(zhí)行。
- 如果在執(zhí)行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被執(zhí)行了的話,那么就不需要再執(zhí)行 UNWATCH 了。
- 因為 EXEC 命令會執(zhí)行事務,因此 WATCH 命令的效果已經(jīng)產(chǎn)生了;而 DISCARD 命令在取消事務的同時也會取消所有對 key 的監(jiān)視,因此這兩個命令執(zhí)行之后,就沒有必要執(zhí)行 UNWATCH 了。
時間復雜度:
- O(1)。
返回值:
- 總是?OK?。
以下是一個使用UNWATCH命令的示例代碼:
127.0.0.1:6379> WATCH lock lock_value
OK
127.0.0.1:6379> UNWATCH
OK
??WATCH(監(jiān)視一個或多個key?,在事務執(zhí)行之前這個或這些 key 被其他命令所改動,那么事務將被打斷)
說明:
- WATCH命令是Redis事務的一部分,用于監(jiān)視一些鍵,一旦這些鍵在事務執(zhí)行之前被其他客戶端修改,則事務會取消執(zhí)行,從而避免了出現(xiàn)死鎖或數(shù)據(jù)不一致的情況。
- 當使用WATCH命令時,客戶端將開始監(jiān)視指定的鍵,如果這些鍵在其他客戶端上被修改,當前客戶端的事務將自動取消執(zhí)行。
時間復雜度:
- O(1)。
返回值:
- 總是返回?OK?。
以下是一個使用WATCH命令的示例代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-541477.html
127.0.0.1:6379> watch key1 # 監(jiān)視一個鍵 (注意:可以一條命令監(jiān)視多個鍵 如:WATCH key1 key2)
127.0.0.1:6379> watch key2 # 再監(jiān)視一個鍵
127.0.0.1:6379> multi # 開始一個事務
127.0.0.1:6379> set("key1", "value1") # 在被監(jiān)視的鍵上進行SET操作
127.0.0.1:6379> set("key2", "value2") # 在被另外
- 當使用WATCH命令監(jiān)視了兩個鍵后,開始一個新事務,并在被監(jiān)視的鍵上執(zhí)行SET操作,如果這些鍵在其他客戶端上被修改,事務會自動取消執(zhí)行。
到了這里,關于【Redis】Transaction(事務)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!