这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战
Redis作为一个非关系型数据库,其也是有事务操作的。
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
(1)批量操作在发送 EXEC 命令前被放入队列缓存。
(2)收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
(3)在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事务从开始到执行会经历以下三个阶段:
(1)开始事务。
(2)命令入队。
(3)执行事务。
但是redis的事务和mysql的事务还是有很大区别的,mysql执行过程中出现错误,数据会回滚,而redis事务执行过程中失败则不会回滚。
Redis的事务可以看做是一个批量执行命令的一个脚本。
这里关注的不是事务执行过程中每条命令是否都执行成功,而是,执行当前的事务是否成功。
一:linux命令
// 开始事务
127.0.0.1:6379> multi
OK
// 设置健值
127.0.0.1:6379> set a aaaa
QUEUED
// 设置健值
127.0.0.1:6379> set b bbbb
QUEUED
// 设置健值
127.0.0.1:6379> set c cccc
QUEUED
// 执行事务,其实redis的事务就是一个批处理命令的一个脚本
127.0.0.1:6379> exec
1) OK
2) OK
3) OK
二:PHP命令
// 开启事务
$res = $redis->multi();
$res = $redis->set('a','aaa');
var_dump($res);
echo "<hr>";
$res = $redis->set('b','bbb');
var_dump($res);
echo "<hr>";
$res = $redis->set('c','bbb');
var_dump($res);
echo "<hr>";
// 执行事务
$res = $redis->exec();
var_dump($res);
以上只是对redis事务简单的应用,大概就是这样,主要应用其是一个批处理的命令。
三:基于redis事务的乐观锁实现
解释:乐观锁(Optimistic Lock), 顾名思义,就是很乐观。
每次去拿数据的时候都认为别人不会修改,所以不会上锁。
watch命令会监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。
也可以调用watch多次监视多个key。这样就可以对指定的key加乐观锁了。
注意watch的key是对整个连接有效的,事务也一样。
如果连接断开,监视和事务都会被自动清除。
当然了exec,discard,unwatch命令都会清除连接中的所有监视。
// 监视 count 值
$redis->watch("count");
// 开启事务
$redis->multi();
// 操作count
$time = time();
$redis->set("count", $time);
// 模拟并发下其他进程进行set count操作 请执行下面操作
// 在shell命令行中执行 set count issimulate;
sleep(40);
// 提交事务
$res = $redis->exec();
$result = $redis->get('count');
if ($res) {
// 成功...
echo "success:" . $result ;
echo "<hr>";
return;
}
// 失败...
echo "fail:" . $result ;
echo "<hr>";
这段测试代码可能要解释一下:
首先我们先监控键count,开启事务之后,将count键的值设置成当前时间戳,程序睡眠40秒,再执行事务操作。这是在理想情况下,就是上边这段代码在没有任何外力影响的情况下的执行事务成功,输出
Success:1502547852
上面是事务执行成功的结果,我们现在来模拟事务执行失败的情况,很简单,还是上边那段代码,在浏览器中执行之后,程序会睡眠40秒,我们在这个时间里模拟另一个进程修改count键的值,在shell中执行set count issimulate;,watch监控的健的值在事务执行过程中被另一进程改变,则此次事务执行失败。输出
fail:issimulate
其实回过头来看,当不同进程修改同一个值得时候,使用事务,就相当于给其加了一个乐观锁。
四:redis事务命令
序号
命令及描述
1
DISCARD
取消事务,放弃执行事务块内的所有命令。
2
EXEC
执行所有事务块内的命令。
3
MULTI
标记一个事务块的开始。
4
UNWATCH
取消 WATCH 命令对所有 key 的监视。
5
WATCH key [key ...]
监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
有好的建议,请在下方输入你的评论。
欢迎访问个人博客 guanchao.site
欢迎访问小程序: