Redis 事务

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

你可能感兴趣的:(Redis 事务)