事務
用來保證程序原子性的一系列操作
當開啟事務后redis會將所有操作記錄單不執行
當執行exec時 將之前記錄的操作一并執行
redis事務只能保證操作的原子性 但不支持數據回滾
下面例子基于 redis 3.2.10 低于此版本可能會略有不同
// 連接redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 開啟事務
$multi = $redis->multi();
if($multi){
$redis->set('aaa',100);
$redis->set('bbb',200);
// 提交事務
$exec = $redis->exec();
// 返回一個數組 : Array ( [0] => 1 [1] => 1 )
// 數組的第一個值為第一個操作 set('aaa',100) 的執行結果 成功為 1 以此類推
print_r($exec);
}
上面例子會一致性執行 set('aaa',100); 和 set('bbb',200);
如果多個操作中有語法或書寫錯誤 則exec時會全都不執行
$multi = $redis->multi();
$redis->set('aaa',100);
$redis->set22('bbb',200);
$redis->lPush('aaa',2000);
$redis->exec();
# 上面3項操作會全都不執行
那么有一種情況 當事務在執行的過程中 其他客戶端又來操作事務中涉及到的值
那么這樣就很容易出現數據錯亂或臟讀的問題
redis 提供了 watch 來監聽一個或多個鍵 如果在事務提交前所監聽的鍵被改變則exec失敗
// 連接redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 監聽一個或多個鍵
$res = $redis->watch(array('aaa','bbb'));
// 開啟事務
if($res){
// 開啟事務
$multi = $redis->multi();
if($multi){
$redis->set('aaa',1000);
$redis->set('bbb',2000);
// 提交事務
$exec = $redis->exec();
// 返回一個數組 : Array ( [0] => 1 [1] => 1 )
// 數組的第一個值為第一個操作 set('aaa',100) 的執行結果 成功為 1 以此類推
print_r($exec);
}
}
# 在watch之后 exec之前 其他客戶端改變所監聽的鍵的值時( 讀取不改變值則不會出發 ) 則當前事務exec則會失敗