【Redis】Redis事务详解,Redis事务支持回滚(不支持悲观锁)
1、redis事物参考:https://baijiahao.baidu.com/s?id=1613631210471699441&wfr=spider&for=pc
(php操作redis命令官方大全:https://github.com/phpredis/phpredis)
2、总结:redis事物不支持悲观锁,支持乐观锁,要实现悲观锁,看业务,同时也有下面一种方法,循环 【watch > multi > doRedisCommand > exec】
3、详解:
PHP使用Redis的Transaction(事务)命令
1.Transaction命令
命令 | 作用 | 返回值 |
---|---|---|
watch | 监视一个或多个key | 总是OK |
multi | 声明事务开始,后续命令将排队按顺序等待exec执行 | 总是OK |
exec | 顺序执行multi之后的命令,如果multi之前使用watch命令监视的键的值发生变化,执行将失败 | 执行成功时返回数组包含每个命令执行结果,失败时原生命令返回null,php-redis扩展方法返回false |
discard | 取消事务 | 总是OK |
unwatch | 取消watch监视,如果watch监视之后执行了exec或discard,会自动取消监视,不必再unwatch | 总是OK |
2.执行事务
<?php /** * Created by PhpStorm. * User: jmsite.cn * Date: 2019/1/24 * Time: 21:03 */ try { $redis = new Redis(); $redis->connect('192.168.75.132', 6379); //开启事务 $redis->multi(); $redis->setex('keyTest', 60, 1); $redis->get('keyTest'); $redis->incr('keyTest'); $redis->get('keyTest'); //执行事务 $ret = $redis->exec(); print_r($ret); } catch (Exception $e){ echo $e->getMessage(); }
执行结果:以数组形式返回了每个命令执行结果
Array
(
[0] => 1
[1] => 1
[2] => 2
[3] => 2
)
3.取消事务
<?php
/**
* Created by PhpStorm.
* User: jmsite.cn
* Date: 2019/1/24
* Time: 21:03
*/
try {
$redis = new Redis();
$redis->connect('192.168.75.132', 6379);
//先设置缓存keyTest为1
$redis->setex('keyTest', 60, 1);
//开启事务
$redis->multi();
$redis->setex('keyTest', 60, 10);
$redis->get('keyTest');
$redis->incr('keyTest');
$redis->get('keyTest');
//取消事务
$redis->discard();
$ret = $redis->get('keyTest');
var_dump($ret);
//查看keyTest
} catch (Exception $e){
echo $e->getMessage();
}
执行结果:keyTest还是原值,并未发生变化
string(1) "1"
4.监视键,并执行事务
<?php
/**
* Created by PhpStorm.
* User: jmsite.cn
* Date: 2019/1/24
* Time: 21:03
*/
try {
$redis = new Redis();
$redis->connect('192.168.75.132', 6379);
//先设置缓存keyTest为1
$redis->setex('keyTest', 60, 1);
//监视keyTest
$redis->watch(array('keyTest'));
//假设在开始监视之后,执行事务之前,keyTest被并发操作redis的其他用户修改了
$redis->setex('keyTest', 60, 10);
//开启事务
$redis->multi();
$redis->incr('keyTest');
//执行事务
$ret = $redis->exec();
var_dump($ret);
$ret = $redis->get('keyTest');
var_dump($ret);
//查看keyTest
} catch (Exception $e){
echo $e->getMessage();
}
执行结果:exec返回false
bool(false)
string(2) "10"
Transaction(事务)命令的关键在于,redis在给我们提供了高性能的同时,虽然命令是原子性的,但无法和我们的php产生上下文关联,这个时候,Transaction(事务)命令就派上了用场
原文地址:https://www.jmsite.cn/blog-601.html