Redis 事务
redis事务介绍
事务可以一次执行多个命令, 并且带有以下三个重要的保证:
- 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。;
- 事务在执行的过程中,其他客户端发送来的命令请求不会插入到当前事务执行序列中;
- 事务是一个原子操作:收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行
事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
注意:redis事务不支持回滚
相关命令
- MULTI
- 说明: multi用于标记一个事务块的开始;事务块内的命令会按照先后顺序被放进一个队列中,最后由exec命令原子性的执行
- 返回:总是返回OK;
- EXEC
- 说明:用于执行所有事务块内的命令;
- 返回:事务块内所有命令的返回值,按命令的执行的先后顺序排列;若事务执行被打断,则返回nil;
- 实例:
10.117.8.188:6379> MULTI OK 10.117.8.188:6379> set string4 'string4' QUEUED 10.117.8.188:6379> set string3 'string3' QUEUED 10.117.8.188:6379> del string QUEUED 10.117.8.188:6379> EXEC 1) OK 2) OK 3) (integer) 1
- DISCARD
- 说明:用于取消事务,放弃执行事务块内所有的命令;
- 返回:总是返回OK;
- 实例:
10.117.8.188:6379> MULTI OK 10.117.8.188:6379> del string4 QUEUED 10.117.8.188:6379> del string3 QUEUED 10.117.8.188:6379> DISCARD OK
- WATCH key [key1 ... ]
- 说明:监视一个或多个key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么将打断事务的执行;WATCH命令在事务执行exec之后,无论执行是否成功,就不在监听这个(或这些)key;客户端关闭,则该客户端的监听就会取消;
- 返回:总是返回OK;
- 实例:
客户端2: set string1 '1111' OK 客户端1: 10.117.8.188:6379> WATCH string1 OK 10.117.8.188:6379> MULTI OK 10.117.8.188:6379> set string1 'string1' QUEUED 10.117.8.188:6379> set string3 'val3' QUEUED 10.117.8.188:6379> EXEC (nil) 由于string1的值发生变化,事务被打断,返回nil;
- UNWATCH
- 说明:取消WATCH监控的所有的key;
- 返回:总是返回OK;
- 实例:
10.117.8.188:6379> UNWATCH OK
事务的错误
- 事务EXEC前的错误:入队的命令出错;入队成功会返回QUEUED,否则就是入队失败;入队如果失败,客户端就会停止并取消该事务;
- 命令可能在EXEC调用之后失败,此时事务中的错误不会被处理,事务会继续往下执行
phpredis使用事务介绍
- multi, exec, discard
- 说明:执行或者退出事务
- 参数:multi和pipeline的作用类似,都是开始一个事务,但是pipeline开启的事务不具有原子性,但是速度比multi更快,multi开启的事务具有原子性;exec执行事务,discard取消事务;
- 实例:事务正常执行
$redis->multi(); //$redis->pipeline(); $redis->set('string1','kkk12'); $redis->set('string2','kooo2'); $redis->get('string1'); $res = $redis->exec(); var_dump($res); //返回值: array(3) { [0]=> bool(true) [1]=> bool(true) [2]=> string(5) "kkk12" } // 事务被取消 $redis->multi(); $redis->set('string1','k234'); $redis->set('string2','kooo2'); $redis->get('string1'); $res = $redis->discard(); var_dump($res); //返回值: bool(true)
- watch(key1,key2,...), unwatch
- 说明:watch监控一个或多个key,unwatch取消所有的监控;如果在multi和exec之间,被监控的key发生变化,则事务执行返回false;
- 参数:一个string类型的key或者多个key组成的数组
- 实例:事务执行过程中被打断
第一段代码: $redis->watch('string1'); $redis->multi(); $redis->set('string1','k234'); $redis->set('string2','kooo2'); $redis->get('string1'); sleep(10); $ret = $redis->exec(); var_dump($ret); 第二段代码: $redis->connect('10.117.8.188',6379); $res = $redis->set('string1','llll1'); var_dump($res); //true 第一段代码exec未执行之前,执行第二段代码,等待第一段代码执行结束,打印$ret:false
有罪是符合人性的,但长期坚持不改就是魔鬼。