Redis和传统的关系型数据库一样,因为具有持久化的功能,所以也有事务的功能!

有关事务相关的概念和介绍,这里就不做介绍。

在学习Redis的事务之前,首先抛出一个面试的问题。

面试官:请问Redis支持事务吗?如果支持和传统的关系型数据的事务有什么区别?

应试者:支持,但是是部分支持。Redis的事务和传统的关系型数据库事务有点不一样,传统的数据库事务一组操作单元,要么全部成功,要么全都失败。而Redis在执行一个命令集合的时候,可能会出现集合的一些命令成功,一些命令失败。

Redis 事务-中文官网:Redis 事务管理

Redis 事务| 菜鸟教程 :Redis 事务

Redis事务的学习笔记总结:

1:是什么?

  1. 可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。

2:能做什么?

  1. 一个队列中,一次性、顺序性、排他性的执行一系列命令

3:常用命令

Redis 事务命令

  1. 1 DISCARD
  2. 取消事务,放弃执行事务块内的所有命令。
  3. 2 EXEC
  4. 执行所有事务块内的命令。
  5. 3 MULTI
  6. 标记一个事务块的开始。
  7. 4 UNWATCH
  8. 取消 WATCH 命令对所有 key 的监视。
  9. 5 WATCH key [key ...]
  10. 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

4:怎么玩?

  • 案例1:正常执行
  1. 127.0.0.1:6379> KEYS *
  2. (empty list or set)
  3. 127.0.0.1:6379> MULTI #开始事务
  4. OK
  5. 127.0.0.1:6379> set k1 v1
  6. QUEUED
  7. 127.0.0.1:6379> set k2 v2
  8. QUEUED
  9. 127.0.0.1:6379> set k3 v3
  10. QUEUED
  11. 127.0.0.1:6379> EXEC #执行,全部执行成功
  12. 1) OK
  13. 2) OK
  14. 3) OK
  15. 127.0.0.1:6379> MGET k1 k2 k3 #查看执行结果
  16. 1) "v1"
  17. 2) "v2"
  18. 3) "v3"
  19. 127.0.0.1:6379>
  • 案例2:放弃事务
  1. 127.0.0.1:6379> MULTI #开始事务
  2. OK
  3. 127.0.0.1:6379> set k4 v4
  4. QUEUED
  5. 127.0.0.1:6379> set k5 v5
  6. QUEUED
  7. 127.0.0.1:6379> set k1 v11 #这里发现出错了,第一次设置k1 了
  8. QUEUED
  9. 127.0.0.1:6379> DISCARD #放弃事务
  10. OK
  11. 127.0.0.1:6379> MGET k1 k2 k3 k4 k5 #k4 k5 的值没有设置成功
  12. 1) "v1"
  13. 2) "v2"
  14. 3) "v3"
  15. 4) (nil)
  16. 5) (nil)
  17. 127.0.0.1:6379>
  • 案例3:全体连坐(一个出错,全部执行失败)
  1. 127.0.0.1:6379> KEYS * #查看当前的keys
  2. 1) "k1"
  3. 2) "k3"
  4. 3) "k2"
  5. 127.0.0.1:6379> MULTI #开始事务
  6. OK
  7. 127.0.0.1:6379> set k4 v4
  8. QUEUED
  9. 127.0.0.1:6379> set k5 v5
  10. QUEUED
  11. 127.0.0.1:6379> getandset k1 #这里有个操作出错 ,下面报错,
  12. (error) ERR unknown command 'getandset'
  13. 127.0.0.1:6379> set k6 v6 # 这个命令依旧执行成功,放到Queued队列
  14. QUEUED
  15. 127.0.0.1:6379> EXEC #执行,出错
  16. (error) EXECABORT Transaction discarded because of previous errors.
  17. 127.0.0.1:6379> MGET k1 k2 k3 k4 k5 k6 #k4 k5 k6 的值都没有设置成功,操作全部失败
  18. 1) "v1"
  19. 2) "v2"
  20. 3) "v3"
  21. 4) (nil)
  22. 5) (nil)
  23. 6) (nil)
  24. 127.0.0.1:6379>
  • 案例4:冤头债主(一个出错,出错的不执行,其他的执行成功!)
  1. 127.0.0.1:6379> set k1 1 #将k1 修改为 1
  2. OK
  3. 127.0.0.1:6379> keys *
  4. 1) "k1"
  5. 2) "k3"
  6. 3) "k2"
  7. 127.0.0.1:6379> MULTI #开启事务
  8. OK
  9. 127.0.0.1:6379> set k4 v4
  10. QUEUED
  11. 127.0.0.1:6379> set v5 v5
  12. QUEUED
  13. 127.0.0.1:6379> INCR k1 #k1 加1
  14. QUEUED
  15. 127.0.0.1:6379> INCR k2 #k2 加1 ,因为k2的值为v2 ,这里最后执行会报错
  16. QUEUED
  17. 127.0.0.1:6379> INCR k3 #k3 加1
  18. QUEUED
  19. 127.0.0.1:6379> set k6 v6
  20. QUEUED
  21. 127.0.0.1:6379> EXEC #执行,除了 k2 k3 执行失败,其他的都执行成功。
  22. 1) OK
  23. 2) OK
  24. 3) (integer) 2
  25. 4) (error) ERR value is not an integer or out of range #INCR k2 执行出错
  26. 5) (error) ERR value is not an integer or out of range #INCR k3 执行出错
  27. 6) OK
  28. 127.0.0.1:6379> MGET k1 k2 k3 k4 v5 k6 #看到k4 v5 k6 设置成功
  29. 1) "2"
  30. 2) "v2"
  31. 3) "v3"
  32. 4) "v4"
  33. 5) "v5"
  34. 6) "v6"
  35. 127.0.0.1:6379>
  • 案例5:watch监控(watch可以监控多个key,使用watch进行key的监控,相当于给key上锁,如果在事务中,监控的key的value发生变化,则整个事务的全部命令都执行失败)
  1. 127.0.0.1:6379> KEYS *
  2. 1) "k3"
  3. 2) "k4"
  4. 3) "k2"
  5. 4) "v5"
  6. 5) "k1"
  7. 6) "k6"
  8. 127.0.0.1:6379> MGET k1 k2 k3 k4 v5 k6
  9. 1) "2"
  10. 2) "v2"
  11. 3) "v3"
  12. 4) "v4"
  13. 5) "v5"
  14. 6) "v6"
  15. 127.0.0.1:6379> WATCH k1 #监控k1 第一步
  16. OK
  17. 127.0.0.1:6379> MULTI #开始事务 第二步
  18. OK
  19. 127.0.0.1:6379> set k7 v7 #第三步
  20. QUEUED
  21. 127.0.0.1:6379> set k2 v2222 #第四步
  22. QUEUED
  23. 127.0.0.1:6379> set k3 v3333 #第五步
  24. QUEUED
  25. 127.0.0.1:6379> set k8 v8 #第六步
  26. QUEUED
  27. 127.0.0.1:6379> EXEC #第七步 #执行结果为nil ,说明执行失败
  28. (nil)
  29. 127.0.0.1:6379> MGET k1 k2 k3 k4 v5 k6 k7 k8
  30. 1) "110" #k1 的值被改了 ,其他的事务中的值都没有成功
  31. 2) "v2"
  32. 3) "v3"
  33. 4) "v4"
  34. 5) "v5"
  35. 6) "v6"
  36. 7) (nil)
  37. 8) (nil)
  38. 127.0.0.1:6379>
  39. --
  40. 在执行第三 —— 第六步之间,使用另一个客户端修改k1 的值为 110
  41. 另一个客服端执行:
  42. 127.0.0.1:6379> set k1 110
  43. OK

案例5解释:因为另一个客服端修改 了k1的值,但是k1的值是被监控的,事务在执行的时候发现k1的值被修改了,则事务中的其他操作命令也不执行,即执行失败。

5:执行阶段

  1. 开启:以MULTI开始一个事务
  2. 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
  3. 执行/撤销:由EXEC/Discard 命令触发/撤销事务

6:总结

  • 单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断
  • 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题
  • 不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

备注知识 :

悲观锁:

  1. 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block
  2. 直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁.

乐观锁:

  1. 乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,
  2. 乐观锁策略:提交版本必须大于记录当前版本才能执行更新

CAS(check and set)

悲观锁和乐观锁相关的参考博文:

Java 中的悲观锁和乐观锁的实现:https://toutiao.io/posts/400085/app_preview

乐观锁的一种实现方式:CAS:http://blog.csdn.net/qq32933432/article/details/51036361


欢迎访问我的csdn博客,我们一同成长!

"不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!"

博客首页:http://blog.csdn.net/u010648555

Redis学习——Redis事务的更多相关文章

  1. Redis学习---Redis操作之Python连接

    PyCharm下的Redis连接 连接方式: 1. 操作模式 redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使 ...

  2. Redis学习——Redis持久化之AOF备份方式保存数据

    新技术的出现一定是在老技术的基础之上,并且完善了老技术的某一些不足的地方,新技术和老技术就如同JAVA中的继承关系.子类(新技术)比父类(老技术)更加的强大! 在前面介绍了Redis学习--Redis ...

  3. Redis 学习(三) —— 事务、消息发布订阅

    一.Redis事务 Redis 提供的事务机制与传统的数据库事务有些不同,传统数据库事务必须维护以下特性:原子性(Atomicity), 一致性(Consistency),隔离性(Isolation) ...

  4. [转]Redis学习---Redis高可用技术解决方案总结

    [原文]https://www.toutiao.com/i6591646189714670093/ 本文主要针对Redis常见的几种使用方式及其优缺点展开分析. 一.常见使用方式 Redis的几种常见 ...

  5. Redis学习——Redis持久化之RDB备份方式保存数据

    从这一个介绍里面知道,redis比memcache作为缓存数据库强大的地方,一个是支持的数据类型比较多,另一个就是redis持久化功能. 下面就介绍Redis的持久化之RDB! 一:什么是redis的 ...

  6. Redis学习手册(事务)

    一.概述: 和众多其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制.在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是我们实现事务的基石.相信对有关系型数据 ...

  7. Redis学习笔记-事务控制篇(Centos7)

    一.事务控制 1.简单事务控制 redis可以使用mult命令将之后的命令都存放在队列中,只有使用exec命令时才全部执行. 127.0.0.1:6379> multi OK 127.0.0.1 ...

  8. Redis学习——redis.conf 配置文件介绍

    学以致用 学在用前 参看文章: redis.conf 配置详解 Redis配置文件详解(redis.conf)-云栖社区 在Redis的使用过程,除了知道对Redis五种数据类型的操作方法之外,最主要 ...

  9. redis学习——redis应用场景

    毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作,为不同的大象 ...

随机推荐

  1. Django创建应用、模型、配置后台自动管理

    1.创建应用 python manage.py startapp myblog 2.应用结构 3.创建模型(models.py) from django.db import models # Crea ...

  2. CSS3笔记之第一天

    通过展示实例来初步学习CSS3 1.背景 设置背景色:background-color:#b0c4de; 设置背景图片:background-image:url('paper.gif'); 设置背景图 ...

  3. 近期学习的原生JS知识以及jQuery框架

    [正则表达式]1.正则表达式包括两部分: ① 定义正则表达式的规则 ② 定义正则表达式的模式(i/g/m)2.声明正则表达式: ① 字面声明 : var reg = /表达式规则/表达式模式 ② 使用 ...

  4. 【grunt】两小时入门

    目录: 1. 用途和场景 2.Grunt插件 3.相关资源 4.环境安装 5.开始学习 5.1 一个新项目 5.2 生成package.json 5.3 在项目中安装grunt和相关插件 5.4 Gr ...

  5. jQuery === 面条式代码?

    自从React/Vue等框架流行之后,jQuery被打上了面条式代码的标签,甚至成了"过街老鼠",好像谁还在用jQuery,谁就还活在旧时代,很多人都争先恐后地拥抱新框架,各大博客 ...

  6. 第1阶段——uboot分析之仿照bootm制作hello命令(7)

    仿照bootm命令生成来制作一个hello命令,功能:打印出hello,world!和参数值 1.点击New File ,创建cmd_hello.c将./common/cmd_bootm.c的头文件复 ...

  7. Java企业微信开发_09_身份验证之移动端网页授权(有完整项目源码)

    注: 源码已上传github: https://github.com/shirayner/WeiXin_QiYe_Demo 一.本节要点 1.1 授权回调域(可信域名) 在开始使用网页授权之前,需要先 ...

  8. 安装JDK详细步骤,以及环境变量配置

    1.JDK 1)下载:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 点击同意, ...

  9. IT行业有前景么?一个10年行内人的6点看法

    本人毕业快11年了. 大学读的建筑专业,却在IT行业干了10年. 真心来讲,我非常感谢好兄弟老唐,是他在我迷茫的那两年,领着我踏入了IT行业,也找到了自己的兴趣爱好. 这些年我经常在知乎.博客等地方发 ...

  10. 获取windows任务栏高度的方法

    方法一: TRect rt; SystemParametersInfo(SPI_GETWORKAREA, , &rt, ); //任务栏在下面的高度 int y = ::GetSystemMe ...