事务
用来保证程序原子性的一系列操作
当开启事务后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则会失败