redis大纲: 

    传送

 

我们先来回顾一下redis的优势:

    速度快!    数据类型丰富!    支持事务!    特性丰富!

    那我们就就来聊一聊redis的事务, 首先我们先聊一下概念性的问题, 再进行测试!

 

redis的事务是什么?

事务是一个单独的隔离操作, 开启事务后所有的命令都会序列化, 按顺序的执行, 在事务执行过程中

     不会被其他客户端发送来的命令打断, 这保证了命令是作为一个独立的单位执行的, redis的事务是原子操作

 

redis事务涉及到的命令:

    MULTI        开启事务

    EXEC         执行事务

    DISCARD  取消执行事务

    WATCH      对某个key加锁 如果这个key被其他客户端修改了 则导致事务失败

    UNWATCH 释放锁

 

redis锁的工作流程:

在修改某个变量前可以对变量进行加锁, 如果其他客户端修改了该变量, 会导致本客户端修改失败

 

redis的锁和传统锁有什么区别?

加锁的客户端允许其他客户端修改, 但是本客户端会报错

 

测试1: 测试事务的执行

    首先我们先查询一下所有的key:   

redis 事务作用 redis的事务有什么用_redis 事务作用

, 现在redis是没有数据的    执行事务  

redis 事务作用 redis的事务有什么用_客户端_02

, 可以看到都是ok, 再来看一下所有的key: 

redis 事务作用 redis的事务有什么用_redis 事务作用_03

,     再开启一个事务, 进行set和incr操作, 

redis 事务作用 redis的事务有什么用_redis 事务作用_04

, 这里因为incr了一个 string的数据,    所以会报错,  再来看一下所有的key,  

redis 事务作用 redis的事务有什么用_客户端_05

, 从这里可以看出 d还是被set了

如果操作在加入到事务队列时没有问题的, 那么事务是会执行的, 事务不能保证原子性

 

 测试2: 测试事务的执行

    执行事务 

redis 事务作用 redis的事务有什么用_客户端_06

, 这里keys下, 查看事务是否插入成功    

redis 事务作用 redis的事务有什么用_客户端_07

,  可以看出, 事务是没有执行的

 如果事务相关的命令中, 中间有语法错误, 则事务最终不会得到执行

 

 测试3: 测试事务的取消

     执行事务 

redis 事务作用 redis的事务有什么用_加锁_08

, 这里keys一下, 

redis 事务作用 redis的事务有什么用_客户端_09

, 可以看出事务被取消了,      再执行事务 

redis 事务作用 redis的事务有什么用_redis_10

, 可以看出命令错误, 但是取消还是执行了,     这里再keys一下, 

redis 事务作用 redis的事务有什么用_客户端_09

, 发现还是没有数据

事务的DISCARD返回肯定是OK, 绝对执行成功, 不会失败

 

测试4: 测试加锁不开启事务 其他客户端修改

    先set一个值, 然后对这个key加锁 

redis 事务作用 redis的事务有什么用_客户端_12

, 这里看到修改成功了, 这时其他客户端修改,     

redis 事务作用 redis的事务有什么用_redis_13

, 可以看到修改成功了, 这时本机修改看看是否报错,    

redis 事务作用 redis的事务有什么用_redis 事务作用_14

, 没有报错并且执行成功

单独的使用 watch 命令是没有作用的

 

测试5: 测试事务加锁 其他客户端不修改

    对a加锁, 开启事务修改a, 

redis 事务作用 redis的事务有什么用_redis 事务作用_15

, 可以看出 非常的正常, 就算没有 watch 和预期结果也是一样的

事务可以不用依赖watch

 

测试6: 测试事务加锁 其他客户端修改

    对a加锁, 开启事务修改a但不执行, 

redis 事务作用 redis的事务有什么用_客户端_16

, 其他客户端修改a, 

redis 事务作用 redis的事务有什么用_客户端_17

,    可以看到a被修改了, 这时执行事务 

redis 事务作用 redis的事务有什么用_加锁_18

, 发现返回nil    这里查看一下a的值, 

redis 事务作用 redis的事务有什么用_redis 事务作用_19

, 可以看出事务未执行

对一个key加锁, 如果其他客户端修改了, 那么事务不会执行

 

测试7: 测试事务加锁 事务中释放锁 其他客户端修改

    对a加锁, 开启事务在第一行释放锁并且修改a但不执行, 

redis 事务作用 redis的事务有什么用_redis_20

, 其他客户端修改a       

redis 事务作用 redis的事务有什么用_客户端_21

,  可以看到a已经被修改, 执行事务 

redis 事务作用 redis的事务有什么用_redis 事务作用_22

,    get 下 a 

redis 事务作用 redis的事务有什么用_加锁_23

, 可以看出值未修改

在事务中释放锁是不成立的

 

测试8: 测试事务不加锁 其他客户端修改

    开启事务修改a但不执行, 

redis 事务作用 redis的事务有什么用_客户端_24

, 其他客户端修改a, 

redis 事务作用 redis的事务有什么用_客户端_21

,

 

    可以看出修改成功, 执行事务, 

redis 事务作用 redis的事务有什么用_加锁_26

 , 可以看出还是修改成功了

事务不依赖锁, 但是锁依赖事务, 不加锁其他客户端修改数据事务还是会执行的

 

总结:

    1. redis的事务不拥有原子性! ACID是关系型数据库特有的

    2. 如果事务中命令有误, 事务最终是不会执行的

    3. 事务不一定加锁

    4. 如果加了锁, 其他客户端修改数据, 事务一定不会执行

    5. 在事务中释放锁是不成立的

    6. discard命令一定会执行成功

 

结束

  这就是我对redis事务篇的总结   感觉有用就点个赞吧 如果有错误或更好的方法评论区请多多指出  相互学习共同进步