Redis交易處理

來源:互聯網
上載者:User

Redis交易處理

當前使用的redis版本
 
#redis-cli  -v
redis-cli 2.6.4

MULTI 、EXEC 、DISCARD 和WATCH 是 Redis 事務的基礎

1.MULTI  命令用於開啟一個事務,它總是返回 OK 。
MULTI 執行之後,用戶端可以繼續向伺服器發送任意多條命令,這些命令不會立即被執行,而是被放到一個隊列中

2.EXEC 命令被調用時,所有隊列中的命令才會被執行。

+++++++++++命令 +++++++++++

redis 192.168.1.53:6379> multi
OK
redis 192.168.1.53:6379> incr foo
QUEUED
redis 192.168.1.53:6379> set t1 1
QUEUED
redis 192.168.1.53:6379> exec
1) (integer) 2
2) OK

+++++++++++對應的java代碼 +++++++++++

Jedis jedis = new Jedis("192.168.1.53", 6379);
Transaction tx = jedis.multi();
tx.incr( "foo");
tx.set( "t1", "2");
List<Object> result = tx.exec();
 
if (result == null || result.isEmpty()) {
    System. err.println( "Transaction error...");
    return ;
}
 
for (Object rt : result) {
    System. out.println(rt.toString());
}
 

使用事務時可能會遇上以下兩種錯誤:
1.事務在執行EXEC 之前,入隊的命令可能會出錯。比如說,命令可能會產生語法錯誤(參數數量錯誤,參數名錯誤,等等),或者其他更嚴重的錯誤,比如記憶體不足

(如果伺服器使用 maxmemory 設定了最大記憶體限制的話)。

2.命令可能在EXEC 調用之後失敗。舉個例子,事務中的命令可能處理了錯誤類型的鍵,比如將列表命令用在了字串鍵上面,諸如此類。

第一種錯誤的情況:
伺服器端:
在 Redis 2.6.5 以前,Redis 只執行事務中那些入隊成功的命令,而忽略那些入隊失敗的命令

不過,從 Redis 2.6.5 開始,伺服器會對命令入隊失敗的情況進行記錄,並在用戶端調用EXEC 命令時,拒絕執行並自動放棄這個事務。
+++++++++++命令 +++++++++++
 
redis 192.168.1.53:6379> multi
OK
redis 192.168.1.53:6379> incr foo
QUEUED
redis 192.168.1.53:6379> set ff 11 22
(error) ERR wrong number of arguments for 'set' command
redis 192.168.1.53:6379> exec
1) (integer) 4

因為我的版本是:2.6.4,所以Redis 只執行事務中那些入隊成功的命令,而忽略那些入隊失敗的命令

用戶端(jredis):

用戶端以前的做法是檢查命令入隊所得的傳回值:如果命令入隊時返回 QUEUED ,那麼入隊成功;否則,就是入隊失敗。如果有命令在入隊時失敗,

那麼大部分用戶端都會停止並取消這個事務。

第二種錯誤的情況:

至於那些在EXEC 命令執行之後所產生的錯誤,並沒有對它們進行特別處理:即使事務中有某個/某些命令在執行時產生了錯誤,事務中的其他命令仍然會繼續執行。
 
+++++++++++命令+++++++++++
 
redis 192.168.1.53:6379> multi
OK
redis 192.168.1.53:6379> set a 11
QUEUED
redis 192.168.1.53:6379> lpop a
QUEUED
redis 192.168.1.53:6379> exec
1) OK
2) (error) ERR Operation against a key holding the wrong kind of value
 
+++++++++++對應的java代碼 +++++++++++

Jedis jedis = new Jedis("192.168.1.53", 6379);
Transaction tx = jedis.multi();
tx.set( "t1", "2");
tx.lpop( "t1");
List<Object> result = tx.exec();
 
if (result == null || result.isEmpty()) {
    System. err.println( "Transaction error...");
    return ;
}
 
for (Object rt : result) {
    System. out.println(rt.toString());
}
 

Redis 在事務失敗時不進行復原,而是繼續執行餘下的命令
這種做法可能會讓你覺得有點奇怪,以下是這種做法的優點:
1.Redis 命令只會因為錯誤的文法而失敗(並且這些問題不能在入隊時發現),或是命令用在了錯誤類型的鍵上面:這也就是說,從實用性的角度來說,失敗的命令是由編程錯誤造成的,而這些錯誤應該在開發的過程中被發現,而不應該出現在生產環境中。
2.因為不需要對復原進行支援,所以 Redis 的內部可以保持簡單且快速。

鑒於沒有任何機制能避免程式員自己造成的錯誤,並且這類錯誤通常不會在生產環境中出現,所以 Redis 選擇了更簡單、更快速的無復原方式來處理事務。

3.DISCARD  命令時,事務會被放棄,事務隊列會被清空,並且用戶端會從事務狀態中退出
+++++++++++命令 +++++++++++ 

redis 192.168.1.53:6379> set foo 1
OK
redis 192.168.1.53:6379> multi
OK
redis 192.168.1.53:6379> incr foo
QUEUED
redis 192.168.1.53:6379> discard
OK
redis 192.168.1.53:6379> get foo
"1"
 

4.WATCH  命令可以為 Redis 事務提供 check-and-set (CAS)行為
被WATCH 的鍵會被監視,並會發覺這些鍵是否被改動過了。如果有至少一個被監視的鍵在EXEC 執行之前被修改了,那麼整個事務都會被取消
 +++++++++++第一條命令 +++++++++++ 

redis 192.168.1.53:6379> watch foo
OK
redis 192.168.1.53:6379> set foo 5
OK
redis 192.168.1.53:6379> multi
OK
redis 192.168.1.53:6379> set foo 9
QUEUED
 

+++++++++++暫停(執行完第二條命令才執行下面的)+++++++++++

redis 192.168.1.53:6379> exec
(nil)
redis 192.168.1.53:6379> get foo
"8"
 

+++++++++++第二條命令+++++++++++

redis 192.168.1.53:6379> set foo 8
OK
 
+++++++++++對應的java代碼 +++++++++++

Jedis jedis = new Jedis("192.168.1.53", 6379);
jedis.watch( "foo");
Transaction tx = jedis.multi();
tx.incr( "foo");
 
List<Object> result = tx.exec();          //運行時在這邊打斷點,然後通過命令列改變foo的值
if (result == null || result.isEmpty()) {
    System. err.println( "Transaction error...");
    return;
}
for (Object rt : result) {
    System. out.println(rt.toString());
}

如果在WATCH 執行之後,EXEC 執行之前,有其他用戶端修改了 mykey 的值,那麼當前用戶端的事務就會失敗。程式需要做的,就是不斷重試這個操作,直到沒有發生碰撞為止。
這種形式的鎖被稱作樂觀鎖,它是一種非常強大的鎖機制。並且因為大多數情況下,不同的用戶端會訪問不同的鍵,碰撞的情況一般都很少,所以通常並不需要進行重試。

Ubuntu 14.04下Redis安裝及簡單測試

Redis叢集明細文檔

Ubuntu 12.10下安裝Redis(圖文詳解)+ Jedis串連Redis

Redis系列-安裝部署維護篇

CentOS 6.3安裝Redis

Redis安裝部署學習筆記

Redis設定檔redis.conf 詳解

Redis 的詳細介紹:請點這裡
Redis 的:請點這裡

本文永久更新連結地址:

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.