更多的数据类型命令可在redis中文官网中查找和学习,下面学习redis的事务。
一、redis事务概述
原子性是指一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
事务是指一系列操作,这些操作要么同时成功,要么同时失败,它是一种原子操作。事务没有隔离级别的概念。
redis的单条命令都具有原子性,但是不保证多条命令的原子性!
想要让redis客户端的多条命令可以不被其他的客户端打断,可以使用事务:
执行事务时,所有的命令都会被顺序地一次性执行,且不会被其他客户端打断。但是redis事务不保证原子性,也就是不支持命令错误时回滚。
需要注意的是:
如果 redis 开启 AOF 模式,在执行 redis 事务之前,redis会先把事务写在磁盘中再执行命令。如果事务执行到一半,redis进程突然就挂了,那么就会导致事务中只有一部分指令执行成功,还有一部分指令还未执行。
这种情况下,在 redis下一次启动时会检测到错误,并退出 redis。使用 redis-check-aof 工具可以对 AOF 文件进行修复,删除掉磁盘中的未执行成功的事务,然后重新启动加载 AOF 文件,redis 就恢复到事务没有执行创建的状态,就可以正常启动了
有关于AOF持久化的内容会在后续文章中整理出来。
二、redis事务命令
步骤:
1、开启事务
multi #开启事务后,接下来执行每条正确的指令都返回 QUEUE,代表命令被放入等待队列,并不会执行
2、命令入队
set <key> <value>
incrby <key> <n>
get <key>
3、执行事务
exec #会按顺序返回事务中每条命令的返回结果,执行完事务后,事务就关闭了
当想要放弃事务时,可用命令:
discard #取消事务,在exec执行命令之前使用
扩展
下面来进行两组测试:
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> sets Sara hello # 事务中命令输错
(error) ERR unknown command `sets`, with args beginning with: `Sara`, `hello`,
127.0.0.1:6379> set Sara hello
QUEUED
127.0.0.1:6379> exec # 事务执行不成功
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set Sara hello
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr Sara # 由于Sara中存的不是integer,在运行时会出错
QUEUED
127.0.0.1:6379> set Jerry world
QUEUED
127.0.0.1:6379> exec
1) (error) ERR value is not an integer or out of range
2) OK
从这两个测试中可以看出:
- 当发生编译型异常时,事务中的命令都不会执行;
- 当发生运行时异常时,事务中的其他命令依然可正常执行,也就是redis事务不保证原子性!
三、redis事务乐观锁
redis事务可以用于监控变量,使用 watch 命令可当做乐观锁来操作:
set money 100 #设置键值对
set cangku:wazi 20
watch money cangku:wazi #监视money和cangku:wazi,是否在监视开启到事务执行的这段时间内发生变化
multi #开启事务
incrby money 30 #money自增30
## 此时客户端2对money的值进行了改变
decrby cangku:wazi 5 #仓库袜子数量自减5
exec #执行事务,此时会发现事务中的命令将都不会被执行
如果发现事务执行失败,则需先解锁:
unwatch #解锁所有被监控的变量
然后再次获取新值进行监控
watch money cangku:wazi