Redis事务

Redis事务的定义

Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化,按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

Redis事务的作用

Redis事务的主要作用(用途)就是串联多个命令防止别的命令插队

Multi、Exec、discard

从输入Multi命令开始。输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前命令队列的命令依次执行。

主队过程中可以通过discard来放弃组队
image

Redis事务正常操作

-----提交事务------
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set key1 v1
QUEUED
127.0.0.1:6379> set key2 v2
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
-----取消提交事务-----
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a1 v1
QUEUED
127.0.0.1:6379> set a2 v2
QUEUED
127.0.0.1:6379> discard
OK

Redis事务错误提交

1、组队中某个命令出现了报告错误,执行时整个的队列都会被取消
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a1 v1
QUEUED
127.0.0.1:6379> set a2 v2
QUEUED
127.0.0.1:6379> set a3
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
2、组队时没有错误,但在执行时出现了错误
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set b1 v1
QUEUED
127.0.0.1:6379> incr b1
QUEUED
127.0.0.1:6379> set b2 v2
QUEUED
127.0.0.1:6379> exec # 成功的成功,失败的失败
1) OK
2) (error) ERR value is not an integer or out of range
3) OK

Redis事务冲突问题及其解决方案

什么是事务冲突问题?

多个线程,想同时修改一个属性,导致属性的结果不符合现实

比如:同一个账户,你和你女朋友一起去取钱,账户中只有10000元,你取5000元,你女朋友取10000元,由于同时取,导致最后账户余额为-5000

解决方案

悲观锁

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

传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读写锁,都是在操作之前先上锁。

乐观锁

顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。拿到该数据时会带一个版本号字段,用这个版本号与数据库中的版本号经行对比,如果相同就修改,不同就放弃修改

乐观锁适用于多读的应用类型,这样可以提高吞吐量(在给定时间段内系统完成的交易数量。即系统的吞吐量越大,说明系统在单位时间内完成的用户或系统请求越多,系统的资源得到充分利用。)。Redis就是利用这种Check-and-Set机制实现事务的。

例子:

--------第一个连接-------------
127.0.0.1:6379> set version 100
OK
127.0.0.1:6379> watch version
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby version 10
QUEUED
127.0.0.1:6379> exec
1) (integer) 110 # 修改成功
--------第二个连接-------------
127.0.0.1:6379> watch version
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby version 20
QUEUED
127.0.0.1:6379> exec
(nil) # 修改失败

Redis事务的三大特性

单独的隔离操作

事务中的所有命令都会序列化(排队),按顺序地执行。事务在执行的过程中,不会被其他客户端发过来的命令请求所打断

没有隔离级别的概念

队列的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行

不保证原子性

事务中如果有一条命令执行失败,其后的命令依然会被执行,没有回滚

posted @   小罗要有出息  阅读(59)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示