Redis中的事务跟其他数据库比如MySql中的概念基本一致。Redis中单个命令的执行是原子性的,但是在事务上并没有任何维持原子性的机制,所以Redis事务的执行不具备原子性。就好比下载图片到本地,其中一张图片下载失败,不会使得已经下载的图片还原,也不会影响后面图片的下载。
s在Redis中,事务可以一次执行多条命令,从开始到执行有三个阶段:开始事务,命令入队,执行事务。
但是并没有事务回滚这个概念,它的批量操作在发送exec命令前被放入缓存队列,收到exec指令后开始执行事务,若事务中的任意一条命令执行失败,其余的命令依然被执行,在事务执行过程中,其他客户端提交的命令请求不会插入到事务执行命令队列中。
multi:标记一个事务的开始
exec执行事务
discard取消事务,放弃执行事务块内的所有命令
watch key监视一个或多个key,如果这个或这些key在事务执行之前被事务外的指令改变,事务会被打断退出
unwatch取消监视
然后说说数据库的切换,Redis客户端一共有16个数据库,编号从0-15,默认是0号
切换指令是select number,但是切换之后数据是不共享的,可以使用指令move key number(移动后源数据库清除)
如图:
然后测试事务的特性
第一种:开启事务,先执行一条正确指令,然后执行一条语法就有错误的指令(指令不会放入队列就报错)
然后获取数据发现都没有改变,说明指令都没有执行,这种情况是由于语法错误的指令导致的,事务根本不会执行,所以事务中的指令都不会执行,
第二种:开启事务,先执行一条正确指令,然后执行一条语法没有错误但编译会出错的指令(指令会放入队列,执行时才会报错)
执行exec时会报错,但是事务执行了,执行第一条指令没有问题,执行第二条时出错,但是事务不会回滚,所以第一条指令生效
然后来说说watch如何使用,watch是监视的意思,如果我们在事务中操作的数据被其他改变了,那么事务在进行操作就是不对的,比如说票数为100,你开启一个事务想要对票数减一,但是在事务执行过程中,票数已经改变了,你再去对原来的数据减一,结果显然不正确。所以我们可以再事务开启前,监视这个变量票数:
先监视,在开启事务,这时我们开启另一个窗口并将数据改变
再回到原来的窗口执行事务,让数据加3(此时数据已被改变)
然后执行事务exec,返回为nil,即执行失败,查看数据发现数据为20,也就是在另一个窗口被改变后的数据,证明由于对数据进行监视,执行事务时监视到数据被改变,所以事务 无法执行。