redis大纲:
我们先来回顾一下redis的优势:
速度快! 数据类型丰富! 支持事务! 特性丰富!
那我们就就来聊一聊redis的事务, 首先我们先聊一下概念性的问题, 再进行测试!
redis的事务是什么?
事务是一个单独的隔离操作, 开启事务后所有的命令都会序列化, 按顺序的执行, 在事务执行过程中
不会被其他客户端发送来的命令打断, 这保证了命令是作为一个独立的单位执行的, redis的事务是原子操作
redis事务涉及到的命令:
MULTI 开启事务
EXEC 执行事务
DISCARD 取消执行事务
WATCH 对某个key加锁 如果这个key被其他客户端修改了 则导致事务失败
UNWATCH 释放锁
redis锁的工作流程:
在修改某个变量前可以对变量进行加锁, 如果其他客户端修改了该变量, 会导致本客户端修改失败
redis的锁和传统锁有什么区别?
加锁的客户端允许其他客户端修改, 但是本客户端会报错
测试1: 测试事务的执行
首先我们先查询一下所有的key: , 现在redis是没有数据的
执行事务 , 可以看到都是ok, 再来看一下所有的key: ,
再开启一个事务, 进行set和incr操作, , 这里因为incr了一个 string的数据,
所以会报错, 再来看一下所有的key, , 从这里可以看出 d还是被set了
得出结论: 如果操作在加入到事务队列时没有问题的, 那么事务是会执行的, 事务不能保证原子性
测试2: 测试事务的执行
执行事务 , 这里keys下, 查看事务是否插入成功
, 可以看出, 事务是没有执行的
得出结论: 如果事务相关的命令中, 中间有语法错误, 则事务最终不会得到执行
测试3: 测试事务的取消
执行事务 , 这里keys一下, , 可以看出事务被取消了,
再执行事务 , 可以看出命令错误, 但是取消还是执行了,
这里再keys一下, , 发现还是没有数据
得出结论: 事务的DISCARD返回肯定是OK, 绝对执行成功, 不会失败
测试4: 测试加锁不开启事务 其他客户端修改
先set一个值, 然后对这个key加锁 , 这里看到修改成功了, 这时其他客户端修改,
, 可以看到修改成功了, 这时本机修改看看是否报错,
, 没有报错并且执行成功
得出结论: 单独的使用 watch 命令是没有作用的
测试5: 测试事务加锁 其他客户端不修改
对a加锁, 开启事务修改a, , 可以看出 非常的正常, 就算没有 watch 和预期结果也是一样的
得到结论: 事务可以不用依赖watch
测试6: 测试事务加锁 其他客户端修改
对a加锁, 开启事务修改a但不执行, , 其他客户端修改a, ,
可以看到a被修改了, 这时执行事务 , 发现返回nil
这里查看一下a的值, , 可以看出事务未执行
得出结论: 对一个key加锁, 如果其他客户端修改了, 那么事务不会执行
测试7: 测试事务加锁 事务中释放锁 其他客户端修改
对a加锁, 开启事务在第一行释放锁并且修改a但不执行, , 其他客户端修改a
, 可以看到a已经被修改, 执行事务 ,
get 下 a , 可以看出值未修改
得出结论: 在事务中释放锁是不成立的
测试8: 测试事务不加锁 其他客户端修改
开启事务修改a但不执行, , 其他客户端修改a, ,
可以看出修改成功, 执行事务, , 可以看出还是修改成功了
得出结论: 事务不依赖锁, 但是锁依赖事务, 不加锁其他客户端修改数据事务还是会执行的
总结:
1. redis的事务不拥有原子性! ACID是关系型数据库特有的
2. 如果事务中命令有误, 事务最终是不会执行的
3. 事务不一定加锁
4. 如果加了锁, 其他客户端修改数据, 事务一定不会执行
5. 在事务中释放锁是不成立的
6. discard命令一定会执行成功
结束
这就是我对redis事务篇的总结 感觉有用就点个赞吧 如果有错误或更好的方法评论区请多多指出 相互学习共同进步