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