Redis事务
Redis事务的定义
Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化,按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
Redis事务的作用
Redis事务的主要作用(用途)就是串联多个命令
防止别的命令插队
Multi、Exec、discard
从输入Multi命令开始。输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前命令队列的命令依次执行。
主队过程中可以通过discard来放弃组队
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事务的三大特性
单独的隔离操作
事务中的所有命令都会序列化(排队),按顺序地执行。事务在执行的过程中,不会被其他客户端发过来的命令请求所打断
没有隔离级别的概念
队列的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行
不保证原子性
事务中如果有一条命令执行失败,其后的命令依然会被执行,没有回滚
· 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语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决