[一]什么是redis的事务

--->redis的事务是一组命令的集合。

--->redis的事务是保证一组命令,要么都执行,要么都不执行。但不支持一组命令中,其中一个或多个执行失败,不支持数据回滚。数据的一致性,由程序员控制。

--->redis的事务还能保证一个事务内的命令依次执行,而不被其他命令插入。试想,客户端 A发送几条命令到redis服务器,客户端B也送了一条命令也到redis服务器上。如果不使用事务,则客户端 B的那条命令就有可能在客户端A的那几条命令中间执行。

 

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务。
  • 命令入队。
  • 执行事务。

序号

命令及描述

1

DISCARD 

取消事务,放弃执行事务块内的所有命令。

2

EXEC 

执行所有事务块内的命令。

3

MULTI 

标记一个事务块的开始。

4

UNWATCH 

取消 WATCH 命令对所有 key 的监视。

5

WATCH key [key ...] 

监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

 

[二]redis事务大白话

--->利用MULTI开启事务,然后发送一组命令。在利用EXEC去依次执行这一组命令。

--->redis的事务说白了就是,有一个收集器,从客户端接受一组命令,然后一起执行。如果客户端在发送exec前断连,则那组命令是不会被执行的。这就是redis的事务。如下图。

redis事务 spring redis事务机制_数据

 

[三]redis事务的错误处理

--->如果一个事务中的某个命令执行出错,redis会怎么处理。2.65版本以后。

(1)第一种:命令语法错误。语法错误是指命令不存在活着命令的参数的个数不对。

  处理:如果一组命令中有语法错误的,则所有命令都不会执行。包括那些语法正确的命令。

(2)第二种:运行错误,是指在命令执行时出现错误。比如:散列类型的命令,操作集合类型的键。

  处理:正确的命令会执行,运行错误的命令不会被执行,已经执行的命令的数据也不会回滚。需要程序员自己在代码中实现回滚。

 

 

[四]WATCH命令

--->WATCH  key

--->该命令会监控某个键。其他客户端和当前客户端对该键的值不做修改,那么当前的客户端接下来提出的事务对该键值的操作就可以执行。否则,当前客户端提出的事务中所有的命令不被执行。

--->一旦执行exec后,当前客户端对键的监控就会失效。

--->例子:A客户端在时间点a监控了x键,B客户端或者A客户端在时间点b(b在a之后)对x键的值做了修改。同时,A客户端用MULTI提出一个事务,发送了一组命名。那么改组命令,在等到A客户端发送EXEC去执行整组命令的时候,该组所有的命令不会被执行。如下图模拟。

redis事务 spring redis事务机制_客户端_02

 

[五]UNWATCH命令

--->unwatch命令可以取消对所有key键的监控。从而不会因为在事务提交执行时,因为监控后,事务声明前有客户端对键做了修改,而阻止事务执行。

 

 

[六]过期时间

--->命令:EXPIRE key seconds (单位。秒。必须整数)

--->让某个键在redis服务器上存活seconds秒后,自动删除。

--->设置成功返回:1,设置失败或键不存在返回:0

--->命令:PEXPIRE key millisecond(单位。毫秒。必须是整数)

--->让某个键在redis服务器上存活 millisecond毫秒后,自动删除

--->命令:TTL key

---> 查看某个key还有多长时间被自动删除

--->如果是永久键,返回-1.如果键不存在返回-2,如果是设置了失效的时间的键返回剩余多少秒就失效的秒数。

--->命令:PERSIST key

--->如果想把设置了失效时间的键,变成永久键。则用该命令。

--->如果过期时间被清除返回1,否则返回0(因为键不存在,或是键本来就是永久的)

&&注意点:如果使用watch命令检测一个拥有过期时间的键,该键时间到期自动删除并不回被watch命令认为该键被改变

redis事务 spring redis事务机制_redis事务 spring_03

 

 

[七]排序  (排序对象,集合,有序集合,列表)

---> 命令:SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ....]] [ASC|DESC] [ALPHA] [STORE destination]

--->该命令可以对列表类型,集合类型和有序集合类型键进行排序。

--->该命令还可以完成与关系数据库中的连接查询相类似的任务

--->sort是redis中最强大,最复杂的命令之一。如果使用不好会造成性能瓶颈。

--->sort命令的时间复杂度是0(n+mlog(m)),其中,n表示要排序的列表(集合或有序集合)中的元素个数,m表示要返回的元素个数。当n较大的时候sort的命令性能越低,并且redis在排序前会建立一个长度为n的容器来存储待排序的元素,虽然是一个临时过程,但如果同时进行较多的大数据量的排序操作则会严重影响性能

--->开发中使用sort命令时需要注意以下几点

1.尽可能减少待排序键中的元素数量(使n尽可能小)

2,使用limit参数只获取需要的数据(使m尽可能小)

3,如果要排序的数据量较大,尽可能使用store参数将结果缓存

 

&例外:当要排序的键类型为有序集合且参考键为常量键名时候容器大小为m,而不是n

 

(1)对列表类型的数据进行排序

redis事务 spring redis事务机制_客户端_04

(2)对有序集合类型排序会忽略元素的分数,值针对元素自身进行排

redis事务 spring redis事务机制_redis_05

(3)SORT命令除了可以排序数字外,还可以通过ALPHA参数实现按照字典顺序排列非数字元素。如果是非数字元素需要排序,没有加ALPHA则会报错

redis事务 spring redis事务机制_客户端_06

(4)BY 参数:语法:BY 参考键。

-->参考键,可以是字符串类型的键,或者是散列类型的某个字段(表示为:键名->字段名)

-->* 表示匹配集合中的元素。如例子中的post:*。匹配所有post:1,post:2,post:3

-->当参考键名不包含*时(即常量键名),与要排序的键中的元素值无关。sort命令将不会执行排序操作。因为redis认为这种情况是没有意义的。也没有执行排序操作。

-->但是在不需要排序,但需要借助sort命令获得与元素相关联的数据时,常量键名很有用。

-->参考键虽然支持散列类型,但是*只能在->的前边(即键名的部分)才有用。在->后(即字段的部分)会被当成字段名本身而不会被理解成占位符,从而被元素替换。即常量键名。所以redis是按照要排序元素的本身进行排序,而不是按照参考键名对要排序的元素进行排序。

redis事务 spring redis事务机制_数据_07

 

(5)GET参数 语法:GET 匹配表达式

--->其不影响排序结果

--->而是从排序结果中,按表达式匹配,返回符合表达式的结果集合。

--->表达式,和by参数的参考键名规则一样,支持字符串和散列类型的键。并使用*作占位符号。

redis事务 spring redis事务机制_数据_08

 

(6)STORE 参数   语法:STORE 键名

-->默认情况下SORT会直接返回排序结果,如果希望保存排序结果。可以使用STORE参数。

-->保存后的键为列表类型的。如果键已经存在则覆盖它

-->排序命令加上store的时候,返回的结果是保存在结果键里的元素个数。

redis事务 spring redis事务机制_客户端_09