Redis 事务
什么是事务
Redis 的事务和 MySQL 的事务概念上是类似的. 都是把⼀系列操作绑定成⼀组.让这⼀组操作·能够批量执行.
Redis 的事务和 MySQL 事务的区别
• 弱化的原⼦性: redis 没有 "回滚机制". 只能做到这些操作 "批量执⾏". 不能做到 "⼀个失败就恢复到 初始状态".
• 不保证⼀致性:不涉及 "约束".也没有回滚. MySQL 的⼀致性体现的是运⾏事务前和运⾏后 , 结果都 是合理有效的, 不会出现中间⾮法状态,而· Redis 的限制少就导致了数据在修改时可能出现问题。
• 不需要隔离性: 也没有隔离级别,因为不会并发执⾏事务(redis 单线程处理请求)
• 不需要持久性: Redis 中的数据是保存在内存的.是否开启持久化,是 redis-server ⾃⼰的事情, 和事务⽆关
Redis 事务的意义就是为了打包,将需要批量执行的命令打包到一起,避免中间插入其他命令。
Redis 事务的本质
Redis 实现事务,本质是引入了队列(每个客户端都有一个),开启事务以后,客户端发送的命令都会发送给服务器,保存到相应的队列中(不会立即执行)。当遇到了“执行事务”的命令后,Redis 会将事务中的命令依次执行,由 Redis 的主线程执行,Redis 会将事务中的命令都执行完再去处理其他的客户端
啥时候需要用到 Redis 事务呢?
当我们需要将多个操作打包后运行,使用事务是比较合适的。
事务操作
开启事务
multi
开启⼀个事务.执⾏成功返回 OK.
开启事务后,接下来输入的命令都会暂存到队列中,等待批量执行
执行事务
exec
示例:
每次添加⼀个操作,都会提⽰ "QUEUED", 说明命令已经进⼊客户端的队列了.真正执⾏ EXEC 的时候, 客户端才会真正把上述操作发送给服务器. 此时就可以获取到上述 key 的值了.
放弃当前事务
此时直接清空事务队列.之前的操作都不会真正执⾏到.
discard
监视事务中的某个键值对
watch key
在执⾏事务的时候,如果某个事务中修改的值,被别的客户端修改了,此时就容易出现数据不⼀致的问题,通过 watch 就可以监控事务中的值是否被别的客户端修改。
假设现在在客户端 1 执行如下命令:
在客户端 1 中监视了 key1 ,开启了事务,事务中需要修改 key1 和 key2 键值对
在客户端 2 执行如下命令:
在客户端 1 的事务还没有执行之前,在客户端 2 中修改 key1 的值
提交事务就会发现由于监视了 key1 ,而 key1 的值在其他客户端被修改了,所以整个事务执行失败,返回了 nil
watch 的原理
在开启事务前 watch(监视) 了一个 key,就会记录这个 key 当前的版本号(版本号是一个简单的整数,每次修改都会使版本号变大,服务器会维护每个 key 的版本号情况)
在真正提交事务的时候,如果发现当前 key 的版本号已经超过了事务开始时的版本号,就说明 key 在其他客户端中已经被修改了,事务就会执行失败(事务中的所有操作都不执行)
UNWATCH
取消对 key 的监控.相当于 WATCH 的逆操作