飞道的博客

【Redis】Redis事务工作原理解析与分布式事务实战(Redis专栏启动)

330人阅读  评论(0)

📫作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C++及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。

        

📫 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。

        

🏆 CSDN博客专家/后端领域优质创作者/内容合伙人、InfoQ签约作者、阿里云专家/签约博主、51CTO专家 🏆

        

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~ 


本文目录

本文导读

一、什么是Redis事务

二、Redis事务的特点

1、Redis事务没有隔离级别的概念

2、Redis不保证原子性

3、Redis 不支持回滚事务

4、Redis事务一致性consistency

5、Redis事务隔离性Isolation

6、Redis事务持久性Durability

三、Redis事务实战

1、Redis 事务语法 

2、Redis事务实现

四、Redis事务执行原理

1、Redis事务执行原理​​​​​​​

2、watch实现监控原理

总结


本文导读

本文主要讲解Redis事务工作原理解析与实战,包括什么是Redis事务,Redis事务的特点,例如Redis事务没有隔离级别的概念、不保证原子性、不支持回滚事务等等,Redis事务实战的语法、实现,Redis事务执行的底层原理以及watch实现监控原理。

一、什么是Redis事务

事务本身是支持同时执行多个命令的集合。事务中的所有命令都将被序列化(串行化),在事务执行期间,队列中的命令将按顺序连续执行,其他客户端提交的命令请求将不会插入到事务执行命令序列中。

Redis事务的本质是命令的集合,同时也具有顺序性、排他性,可以一次执行多个命令。

二、Redis事务的特点

1、Redis事务没有隔离级别的概念

批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。

2、Redis不保证原子性

Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。

3、Redis 不支持回滚事务

What about rollbacks?Redis does not support rollbacks of transactions since supporting rollbacks would have a significant impact on the simplicity and performance of Redis.

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

Redis 在事务失败时不进行回滚,而是继续执行余下的命令。Redis命令只会由于语法错误或者命令使用在错误类型的键上失败。因为支持回滚会对Redis的简单性和性能产生重大影响,所有不需要对回滚进行支持,Redis 的内部可以保持简单且快速。

4、Redis事务一致性consistency

Redis事务可以确保在命令失败时回滚,数据可以恢复到执行前的状态,除非Redis进程意外终止。

5、Redis事务隔离性Isolation

Redis事务严格遵守隔离,因为Redis是单进程和单线程模式,可以确保命令执行过程不会被其他客户端命令中断。然而,Redis不像其他结构化数据库那样具有隔离级别设计。 

6、Redis事务持久性Durability

Redis事务不能保证持久性。这是因为RDB和AOF在Redis持久性策略中都是异步执行的。出于性能考虑,无法保证持久性。

三、Redis事务实战

1、Redis 事务语法 

一个事务从开始到执行会经历以下三个阶段:开始事务、命令入队、执行事务。

Redis提供了以下5个基本指令,MULTI、EXEC、DISCARD、WATCH、UNWATCH。

命令

格式

作用

返回值

MULTI

MULTI

标记一个事务块的开始。

显式开启Redis事务,后续命令将排队,等候使用EXEC进行原子执行

always OK.

EXEC

EXEC

执行所有事务块内的命令。

执行事务中的commands队列,恢复连接状态。如果WATCH在之前被调用,只有监测中的Keys没有被修改,命令才会被执行,否则停止执行(详见下文,CAS机制)

成功: 返回数组 —— 每个元素对应着原子事务中一个 command的返回结果;
失败: 返回NULL(Ruby 返回nil);

DISCARD

DISCARD

取消事务,放弃执行事务块内的所有命令。

清除事务中的commands队列,恢复连接状态。如果WATCH在之前被调用,释放监测中的Keys

always OK.

WATCH

WATCH key [key ...]

监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

将给出的Keys标记为监测态,作为事务执行的条件

always OK.

UNWATCH

UNWATCH

取消 WATCH 命令对所有 key 的监视。

清除事务中Keys的监测态,如果调用了EXEC或者 DISCARD,则没有必要再手动调用UNWATCH

always OK.

开启并执行事务


  
  1. # 开启事务
  2. MULTI
  3. # 命令入队
  4. set key1 1
  5. set key2 2
  6. # 执行事务
  7. EXEC

开启并取消事务


  
  1. # 开启事务
  2. MULTI
  3. # 命令入队
  4. set key1 1
  5. set key2 3
  6. # 取消事务
  7. DISCARD
  8. # 观察数据未被改动
  9. get key2

WATCH监控


  
  1. # 事务开始前用WATCH监控k1
  2. WATCH k1
  3. set k1 11
  4. # 开启事务
  5. MULTI
  6. # 修改k1值
  7. set k1 v1
  8. # 执行事务,发回nil,说明事务回滚
  9. EXEC
  10. (nil)
  11. get k1
  12. "11"

2、Redis事务实现

基于Lua脚本,Redis可以确保脚本中的命令以一次性和顺序的方式执行。同时,它不提供事务运行错误的回滚。如果某些命令在执行过程中运行不正确,其余命令将继续运行

基于中间标记变量,使用另一个标记变量来标识事务是否完成。读取数据时,首先读取标记变量以确定事务是否完成。然而,这将需要额外的代码来实现,这很麻烦

四、Redis事务执行原理

1、Redis事务执行原理​​​​​​​​​​​​​​

当客户端切换到事务状态时,服务器将根据客户端发送的不同命令执行不同的操作:如果客户端发送的命令是EXEC、DISCARD、WATCH和MULTI之一,服务器将立即执行该命令。

相反,如果客户端发送的命令不是EXEC、DISCARD、WATCH和MULTI,则服务器不会立即执行该命令,而是将该命令放置在事务队列中,然后向客户端返回QUEUED应答。

2、watch实现监控原理

WATCH命令可以为Redis事务提供检查和设置 check-and-set (CAS)行为。监控WATCH键,以查看它们是否已更改。

如果在执行EXEC之前至少修改了一个受监控的密钥,则整个事务将被取消。EXEC返回 nil,表示事务已失败。如果另一个客户端在WATCH之后和EXEC之前修改键值,则当前客户端的事务将失败。

程序需要做的是重试操作,直到没有冲突。这种类型的锁被称为乐观锁,在大多数情况下,不同的客户端将访问不同的密钥,并且很少发生冲突,因此通常不需要重试。

Redis 使用 WATCH 命令来决定事务是继续执行还是回滚,在这种情况下,您需要在 MULTI 之前使用WATCH监视某些键值对,然后使用 MULTI 命令启动事务并执行数据结构操作的各种命令。此时,这些命令将排队。

当EXEC用于执行事务时,它将首先比较 WATCH 监视的键值对。如果没有更改,它将执行事务队列中的命令并提交事务;如果发生更改,将不会执行事务中的任何命令,并且将回滚事务。当然,无论是否回滚,Redis 都会在事务之前取消 WATCH 命令。

总结​​​​​​​

本文主要讲解Redis事务工作原理解析与实战,包括什么是Redis事务,Redis事务的特点,例如Redis事务没有隔离级别的概念、不保证原子性、不支持回滚事务等等,Redis事务实战的语法、实现,Redis事务执行的底层原理以及watch实现监控原理。 


转载:https://blog.csdn.net/FMC_WBL/article/details/128322303
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场