云边日落 疏影横斜水清浅,暗香浮动月黄昏。 (宋·林逋·山园小梅)
歌曲封面 未知作品
  • 歌曲封面“魔女の宅急便”~ルージュの伝言松任谷由実

渝ICP备2021002886号-1

渝公网安备50022502000591号

网站已运行 3 年 330 天 20 小时 33 分

Powered by Typecho & Sunny

3 online · 41 ms

Title

NoSQL学习之事务

醴都_collect

·

Article
⚠️ 本文最后更新于2021年07月13日,已经过了1039天没有更新,若内容或图片失效,请留言反馈

前言:宁可一思进,莫要一思停

文章大部分参考尚硅谷redis课程的笔记。

事务

为什么需要事务(经典例子)
经典的银行转账行为,A账户转给B账户10元,数据库操作需要两步,第一步A账户减10元,第二步B账户加10元,如果没有事务并且在两步中间发生异常,就会导致A的账户少了10元,但B的账户没有变化,如果不能保证这两步操作统一,银行的转账业务也没法进行展开了。

redis的原子性

  • redis事务的原子性是说的:一次事务提交的多个命令,要么都不执行(watch发现某个key的值变了则不开始执行),要么所有的命令都执行(一旦开始执行事务,事务中所有的命令都会执行,即使有命令报错了,后面的命令也会执行)
  • redis的报错并不会回滚
    -只有当被调用的Redis命令有语法错误时,这条命令才会执行失败(在将这个命令放入事务队列期间,Redis能够发现此类问题),或者对某个键执行不符合其数据类型的操作:实际上,这就意味着只有程序错误才会导致Redis命令执行失败,这种错误很有可能在程序开发期间发现,一般很少在生产环境发现。Redis已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为Redis不需要事务回滚的能力。

是什么

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

    能干吗

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

    常用命令
    kr1yy69e.png

redis的处理事务的五种方式

正常执行

正常执行的相关的命令
kr1z401d.png

放弃事务

输入discard会放弃当前事务
kr1z7d6h.png

放弃全部

当redis可以直接判断出命令出错时会放弃当前的事务
kr1za47d.png

个体放弃

当执行的事务时命令出错不会影响事务的进行
kr1zcw7p.png

Watch监控
  • Redis使用WATCH命令实现事务的“检查再设置”(CAS——Check And Set)行为。
  • 作为WATCH命令的参数的键会受到Redis的监控,Redis能够检测到它们的变化。在执行EXEC命令之前,如果Redis检测到至少有一个键被修改了,那么整个事务便会中止运行,然后EXEC命令会返回一个Null值,提醒用户事务运行失败。所有的WATCH命令都会在被调用之时立刻对相应的键进行监控,直到EXEC命令被调用之时为止

乐观锁

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

悲观锁

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

watch监控示范

背景:old给new转账(无加塞)
无加塞篡改,先监控再开启multi,
保证两笔金额变动在同一个事务内
事务举例1.PNG
事务举例2.PNG

old被转账(有加塞)
监控了key,如果key被修改了,后面一个事务的执行失效
事务举例3.PNG

unwatch取消监控

  • 在知道watch的key被更改时可以unwatch

kr21481l.png
疑问:既然EXEC 命令会执行事务,因此 WATCH 命令的效果已经产生了;而 DISCARD命令在取消事务的同时也会取消所有对 key 的监视,那unwatch有什么用?

小结

  • Watch指令,类似乐观锁,事务提交时,如果Key的值已被别的客户端改变, 比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行
  • 通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化, EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败

3阶段

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

3特性

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

不遵循传统的ACID中的AI

现在已有 0 条评论,0 人点赞
Comment
发表
搜 索 消 息 足 迹
你还不曾留言过..
你还不曾留下足迹..
博主