2011-08-10 68 views
0

如果一個命令失敗,在redis中是否有辦法使'多個'事務中的所有命令都失敗。Redis Multi確保原子性

例如。

<?php 
//using phpredis 
//connection made 

$redis->set('c', 1); 
$res = $redis->multi() 
     ->get('b') 
     ->get('c') 
     ->exec(); 
?> 

$ res將包含1,false。 在Redis中有一種方法可以讓$ res返回false,並且如果其中一個命令失敗,交易將失敗?

回答

2

從Redis的文檔上transactions

需要注意的是,即使在命令失敗時,所有在隊列中的其他 命令進行處理是很重要的 - Redis的不會停止命令的 處理。

根據this文章似乎Redis的交易包括ACID語義只部分並沒有回滾相當於儘管discard條命令可以用來中止交易。

1

回滾和丟棄之間的真正區別是什麼?例如,在SQL Server中,在事務內部,我檢查每條語句的錯誤,然後有條件地中止事務。

在這裏,您可以使用Redis的ERR響應,例如phpredis正確處理,作爲錯誤條件。

下面的代碼檢測到一個失敗的ZADD作爲示例。

$redis = new Redis(); 
$redis->connect('127.0.0.1',6379); 
$redis->multi(); 
$redis->set('ch1',1978); //good command 
$f = $redis->zadd('ch2',1231); //this will fail 
if (!$f) { 
    $redis->discard(); 
    echo "Transaction aborted"; 
} 
else { 
    $redis->exec(); 
    echo "Transaction committed"; 
} 
+1

的Redis只會返回'了'EXEC'命令之前ERR'響應命令是否明顯無效 - 語法錯誤,不正確的密鑰類型,等等。在你的榜樣上面,'ZADD'沒有第三個參數,所以它是無效的。 – dunedain289

0

沒有回退,因爲它沒有那麼多的意義Redis的。它會帶來的開銷太過不成比例。

Redis操作失敗的可能性太低。從官方文檔:交易

錯誤交易有可能會遇到兩種命令錯誤時: 的命令可能無法進行排隊,所以有可能是一個錯誤之前EXEC是調用。

例如,該命令可能在語法上是錯誤的(參數的錯誤數量,錯誤的命令名稱...),或者可能存在一些關鍵條件,如內存不足的情況(如果服務器配置爲具有內存使用maxmemory指令限制)。

在調用EXEC後,命令可能會失敗,例如,因爲我們對具有錯誤值的鍵執行操作(如針對字符串值調用列表操作)。

這種錯誤是可以預防的,它們可以在開發過程中發現。

您可以在這裏更多的瞭解它:https://redis.io/topics/transactions