从零开始Redis(十一)

119 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

🍊作者简介:少年不想说话,努力长大

🍊往期回顾:从零开始Redis(十)

🍊近期目标:写完基础源码,点赞👍🏼、收藏⭐、留言📩

前面大概说完了redis的大部分结构,今天我们看看redis的事务操作,看看Redis是如何做事务处理的;

redis的事务

首先我们知道的是redis它在执行命令的时候是单线程操作的,这也就意味着我们如果存在多个命令,需要一个一个执行,好比我们操作数据库两张表,一张表加,一张表减对应着我们redis的两个命令,为了保证数据的同步变化,数据库有事务进行控制,那redis称为NoSQL自然也要进行事务控制; 这里我们提前先说下,redis它的事务是不保证其原子性的,它主要是串行化我们的命令按顺序执行,保证在这个操作过程中不会别其他命令插队,在我们提交命令的时候并不会执行这些命令,而是先提交这些命令,等到执行命令的时候才会去执行这些命令, 由于不能保证其原子性,所以事务中如果有某个命令执行失败的话并不会回滚,而是继续执行其后的命令;

我们看下事务相关的命令: 

multi 表示标记一个事务块的开始,然后我们就可以按顺序将我们的命令放入队列,

EXEC表示执行队列中事务块的命令, 

127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> set aname zs
QUEUED
127.0.0.1:6379> set anum 23
QUEUED
127.0.0.1:6379> INCR aname
QUEUED
127.0.0.1:6379> INCR anum
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) (error) ERR value is not an integer or out of range
4) (integer) 24

通过上面可以看到由于aname不可以incr,所以报错了,但anum却可以,并返回了+1的结果,以此说明它的原子性,不可打断这块不好验证,相当于一个命令执行一个安全的集合,集合里的操作如果报错就catch是不是好理解点,就记住就行吧;对于DISCARD,取消事务这里我就不多说了,有兴趣自己练习;

在执行的时候我们要说下watch命令,WATCH key [key ...],表示监视一个(或多个) key ,如果在事务执行之前key被其他命令所改动,那么事务将被打断。话不多说,我们看下面例子

127.0.0.1:6379> set num 2
OK
127.0.0.1:6379> watch num
OK
127.0.0.1:6379> set num 5
OK
127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> set num 6
QUEUED
127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> get num
"5"

通过用例我们可以看到在watch后我们修改了num值,导致了后面的事务并没有被执行;UNwatch也是一样,咱们不多说,了解即可,其实redis的事务用到的好像还真。。。反正我是没遇到过,毕竟它失去了原子性,所以我们又怎么能相信它呢;后面我们会看到lua脚本,我们会用lua来实现redis的原子操作,到时我们会进行深入;好啦🥗🥗🥗;

结束结束,那就🛴🛴🛴

如果对你有所帮助

点个赞呗