一、Redis 的事务
Redis 的事务允许在一次单独的步骤中执行一组命令,并且能够保证将一个事务中的所有命令序列化,然后按顺序执行;
在一个 Redis 事务中,Redis 要么执行其中的所有命令,要么什么都不执行。即 Redis 的事务要能够保证序列化和原子性。
二、Redis 事务的常用命令
1.multi
功能:用于标记事务块的开始。Redis 会将执行 multi 命令之后的命令逐个放入队列中,然后才能使用EXEC 命令原子化地执行这个命令序列。
返回值:开启成功返回OK
127.0.0.1:6379> multi //开启事务
OK
127.0.0.1:6379> set k1 v1 //在事务内执行的 redis 命令都会压栈不执行,只有遇到 exec 是才会全部执行
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
2.exec
功能:在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态;
如果在把命令压入队列的过程中报错,则整个队列中的命令都不会执行,执行结果报错;
如果在压队列的过程中正常,在执行队列中某一个命令报错,则只会影响本条命令的执行结果,其它命令正常运行;
当使用 WATCH 命令时,只有当受监控的键没有被修改时,EXEC 命令才会执行事务中的命令;而一旦执行了 exec 命令,之前加的所有watch监控全部取消。
返回值:这个命令的返回值是一个数组,其中的每个元素分别是原子化事务中的每个命令的返回值
当使用 WATCH 命令时,如果事务执行中止,那么 EXEC 命令就会返回一个 Null 值。
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> incr k1
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) ERR value is not an integer or out of range
3.discard
功能:清除所有先前在一个事务中放入队列的命令,并且结束事务;
如果使用了WATCH命令,那么DISCARD命令就会将当前连接监控的所有键取消监控。
返回值:清除成功,返回OK。
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
4.watch key [key …]
功能:当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的;
如果被监控的key值在本事务外有修改时,则本事务所有指令都不会被执行。Watch命令相当于关系型数据库中的乐观锁。
返回值:监控成功,返回OK。
//开启事务1 监控 balance 并且开启一个事务对其值进行修改,
127.0.0.1:6379> set balance 1000
OK
127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby balance
QUEUED
// 此时该事务1还没执行,事务2执行了,并且对balance的值进行修改
//开启事务2 对 balance 值进行修改,
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby balance 500
QUEUED
127.0.0.1:6379> exec
1) (integer) 500
// 此时该事务2执行成功,balance 被改为500
//继续执行事务1 对 balance 值进行修改,
127.0.0.1:6379> exec
(nil)
// 此时由于balance被其他事务修改,所以无法修改balance的值
5.unwatch
功能:清除所有先前为一个事务监控的键;
如果在watch命令之后你调用了EXEC或DISCARD命令,那么就不需要手动调用UNWATCH命令。
返回值:监控成功,返回OK。
127.0.0.1:6379> set balance 1000
OK
127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> unwatch balance
OK
127.0.0.1:6379> incrby balance
QUEUED
127.0.0.1:6379> exec
1) (integer) 1500
三、小结
-
单独的隔离操作:事务中的所有命令都会序列化、顺序地执行。事务在执行过程中,不会被其它客户端发来的命令请求所打断,除非使用 watch 命令监控某些键。
-
不保证事务的原子性:redis 同一个事务中如果一条命令执行失败,其后的命令仍然可能会被执行,redis 的事务没有回滚。Redis 已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为 Redis 不需要事务回滚的能力。
写在最后
以上关于 Redis 中事务的内容,后续如果有时间的话我也将持续更新,如果有错误或者是哪里不足的地方,欢迎各位大大提出宝贵的意见呀~
此外,想了解关于 Redis 的一些其他使用方法可以关注下方公众号,后台回复 “redis ”即可获取,期待着您的光临~
相关链接:
链接: 011 - Redis 的持久化.
链接: 010 - Redis的配置文件.
链接: 009- Redis 数据结构 - zset类型.