Redis事务

在这里插入图片描述

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人
个人主页:Leo的博客
当前专栏: Java从入门到精通
✨特色专栏: Redis7从实战到高级
本文内容:Redis事务
️个人小站 :个人博客,欢迎大家访问
个人知识库:Leo知识库,欢迎大家访问

1. 什么是Redis事务

官网: https://redis.io/docs/manual/transactions/

我这里做了一些简单的翻译

Redis事务_第1张图片

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

总结说:Redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。

2. Redis中的事务处理

我们对数据库中事务处理的相关理论有了一个基本的认识,或许这个世界上的数据库系统千差万别,但我相信在事务处理这个问题上它们最终会殊途同归,就像我们解决并发过程中的冲突问题,常规的做法依然是加锁一样,这是我之所以要花费精力去理解和解释这些理论知识的原因,技术可谓是日新月异,如果我们总是一味地为新技术而疲于奔命,那么或许我们会渐渐地失去对这个行业的热爱,我相信原理永远比框架更为重要。

redis事务提供了一种“将多个命令打包, 然后一次性、按顺序地执行”的机制, 并且事务在执行的期间不会主动中断 —— 服务器在执行完事务中的所有命令之后, 才会继续处理其他客户端的其他命令。

Redis中的事务是可以视为一个队列,即我们可以通过MULTI开始一个事务,这相当于我们声明了一个命令队列。接下来,我们向Redis中提交的每条命令,都会被排入这个命令队列。当我们输入EXEC命令时,将触发当前事务,这相当于我们从命令队列中取出命令并执行,所以Redis中一个事务从开始到执行会经历 开始事务命令入队执行事务 三个阶段。下面是一个在Redis中使用事务的简单示例:

127.0.0.1:6379> MULTI 
OK 
127.0.0.1:6379> SET name "Leo" 
QUEUED 
127.0.0.1:6379> SADD Program_Language "C++" "C#" "Jave" "Python"  
QUEUED 
127.0.0.1:6379> GET name 
QUEUED 
127.0.0.1:6379> EXEC 
1) OK 
2) (integer) 4 
3) "Leo" 

我们可以注意到Redis中的事务和通常意义上的事务基本上是一致的,即

  • 事务是由一系列操作组成的单个逻辑工作执行单元。特别地,因为在Redis中命令是存储在一个队列中,所以,事务中的所有命令都会按顺序执行,并且在执行事务的过程中不会被客户端发送的其它命令中断。
  • 事务是一个原子操作,事物中的命令只有两种执行结果,即全部执行或者全部不执行。如果客户端在使用MULTI命令开启事务后因为意外而没有执行EXEC命令,则事务中的所有命令都不会执行。同理,如果客户端在使用MULTI命令开启事务后执行EXEC命令,则事务中的所有命令都会执行。
  • Redis中的事务可以使用DISCARD命令来清空一个命令队列,并放弃对事务的执行。如果命令在入队时发生错误,Redis将在客户端调用EXEC命令时拒绝执行并取消事务,但是在EXEC命令执行后发生的错误,Redis将选择自动忽略。

3. Redis事务 VS 数据库事务

1.单独的隔离操作 Redis的事务仅仅是保证事务里的操作会被连续独占的执行,redis命令执行是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的
2.没有隔离级别的概念 因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了
3.不保证原子性 Redis的事务不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
4.排它性 Redis会保证一个事务内的命令依次执行,而不会被其它命令插入

Redis事务和MySQL事务有以下不同点:

  1. 基于不同的存储方式:Redis是内存数据库,而MySQL是关系型数据库。因此,Redis将所有的数据存储在内存中,而MySQL将数据存储在磁盘上。这导致Redis的事务处理速度更快,但是不够持久。而MySQL的事务处理速度较慢,但更加稳定可靠。
  2. 事务处理的隔离级别不同:MySQL支持ACID属性的事务处理,并支持四种隔离级别(读未提交,读已提交,可重复读和串行化),而Redis不支持隔离级别。因此,在Redis中执行事务时,所有的命令都是按顺序执行的,没有并发执行的概念。
  3. 回滚处理不同:Redis和MySQL的事务都支持回滚操作,但实现方式不同。在Redis中,当事务中的某个命令执行失败时,整个事务将回滚,之前执行的所有命令都不会生效。而在MySQL中,事务可以根据隔离级别进行回滚,只回滚已提交的事务,未提交的事务不会被回滚。
  4. 支持的数据类型不同:Redis支持更多的数据类型,例如字符串、哈希、列表、集合和有序集合等,而MySQL只支持关系型数据。

总的来说,Redis和MySQL事务处理有很多不同之处,它们各自适用于不同的场景。如果需要高并发的数据操作,可以使用Redis事务;如果需要对数据进行持久化存储和复杂的数据关联查询,则可以使用MySQL事务。

4. 如何使用Redis事务

官网: https://redis.io/docs/manual/transactions/

Redis事务_第2张图片

4.1 Redis事务常用命令

Redis事务_第3张图片

4.2 case1:正常执行 MULTI EXEC

Redis事务_第4张图片

4.3 case2:放弃事务 MULTI DISCARD

Redis事务_第5张图片

4.4 case3:全体连坐

官网说明:

Redis事务_第6张图片

Redis事务_第7张图片

一个语法出错,全体连坐。如果任何一个命令语法有错,Redis会直接返回错误,所有的命令都不会执行

4.5 case4:冤头债主

官网说明:

Redis事务_第8张图片

补充:

Redis事务_第9张图片

Redis事务_第10张图片

注意和传统数据库事务的区别,不一定要么全部成功要么全部失败

4.6 case5:watch监控

  • Redis使用Watch来提供乐观锁定,类似于CAS(Check-and-Set)

    1. 悲观锁:悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁

    2. 乐观锁:乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。

      乐观锁策略:提交版本必须大于记录当前版本才能执行更新

    3. CAS

      Redis事务_第11张图片

  • watch key [key …]

    1. 初始化 k1k2 两个key,先监控在开启multi,保证两个key变动在同一个事务内

      Redis事务_第12张图片

      1. 有加塞篡改:watch命令是一种乐观锁的实现,Redis在修改的时候会检测数据是否被更改,如果被更改了,则执行失败

      Redis事务_第13张图片

      图中3和4不管哪个先执行,最终的结果都是整个事务执行失败

      Redis事务_第14张图片

  • unwatch

    Redis事务_第15张图片

  • 小结

    一旦执行了exec之前加的监控锁都会被取消掉

    当客户端连接丢失的时候(比如退出链接),所有东西都会被取消监视

4.7 总结

开启:multi 开始一个事务

入队: 将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面

执行:exec 命令触发事务

你可能感兴趣的:(Redis从实战到高级,redis,数据库,缓存)