Redis事务失效的三种场景

简介: Redis事务失效的三种场景

Redis事务失效的三种场景


文章目录

Redis 事务失效的三种场景

Redis事务失败,有三种类型的失败场景:

命令入队报错

在事务提交之前,客户端执行的命令缓存(队列)失败,比如命令的语法错误(命令参数个数错误,不支持的命令等等)。

如果发生这种类型的错误,Redis将向客户端返回包含错误提示信息的响应,同时Redis会清空队列中的命令并取消事务。

示例代码如下,开启一个客户端:

127.0.0.1:6379> set name mengmeng   # 事务之前执行
OK
127.0.0.1:6379> multi         # 开启事务
OK
127.0.0.1:6379> set name qianqian   # 事务中执行,命令入队列
QUEUED
127.0.0.1:6379> setset name qianqian2   # 错误的命令,模拟失败场景
(error) ERR unknown command `setset`, with args beginning with: `name`, `qianqian2`,
127.0.0.1:6379> exec        # 提交事务,发现由于上条命令的错误导致事务已经自动取消了
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> get name      # 查询name,发现未被修改
"mengmeng"

最后发现事务里语句失效

命令执行报错

事务提交后开始顺序执行命令,之前缓存在队列中的命令有可能执行失败。

示例代码如下,开启一个客户端:

127.0.0.1:6379> multi       # 开启事务
OK
127.0.0.1:6379> set name mengmeng   # 设置名字
QUEUED
127.0.0.1:6379> set age 18      # 设置年龄
QUEUED
127.0.0.1:6379> lpush age 20    # 此处仅检查是否有语法错误,不会真正执行
QUEUED
127.0.0.1:6379> exec        # 提交事务后开始顺序执行命令,第三条命令执行失败
1) OK
2) OK
3) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get name      # 第三条命令失败没有将前两条命令回滚
"mengmeng"

最后发现事务里语句失效

乐观锁导致失效

由于乐观锁失败,事务提交时将丢弃之前缓存的所有命令序列。

watch 监控 key 所起的作用实际上是一个乐观锁,它所监控的是在事务期间有没有其他客户端对所监控的值进行修改

在Redis中可以通过开启两个redis客户端并结合watch命令模拟这种失败场景。

示例代码如下,开启两个客户端:

# 客户端1
127.0.0.1:6379> set name mengmeng   # 客户端1设置name
OK
127.0.0.1:6379> watch name      # 客户端1通过watch命令给name加乐观锁
OK
# 客户端2
127.0.0.1:6379> get name      # 客户端2查询name
"mengmeng"
127.0.0.1:6379> set name qianqian   # 客户端2修改name值
OK
# 客户端1
127.0.0.1:6379> multi         # 客户端1开启事务
OK
127.0.0.1:6379> set name lili     # 客户端1修改name
QUEUED
127.0.0.1:6379> exec        # 客户端1提交事务,返回空
(nil)
127.0.0.1:6379> get name      # 客户端1查询name,发现name没有被修改为lili
"qianqian"


相关文章
|
缓存 NoSQL Redis
Redis 事务
10月更文挑战第18天
229 1
|
10月前
|
监控 NoSQL 关系型数据库
Redis:事务(Transactions)
Redis事务支持将多个命令打包执行,但与MySQL不同,它不保证原子性、一致性、持久性和隔离性。Redis事务的核心在于“打包”命令,避免其他客户端插队,通过MULTI、EXEC、DISCARD等命令实现。此外,Redis提供WATCH和UNWATCH机制,用于监控键变化,实现类似“乐观锁”的功能,提升并发操作的安全性。
|
监控 NoSQL Java
场景题:百万数据插入Redis有哪些实现方案?
场景题:百万数据插入Redis有哪些实现方案?
311 1
场景题:百万数据插入Redis有哪些实现方案?
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
399 6
|
NoSQL 算法 安全
redis分布式锁在高并发场景下的方案设计与性能提升
本文探讨了Redis分布式锁在主从架构下失效的问题及其解决方案。首先通过CAP理论分析,Redis遵循AP原则,导致锁可能失效。针对此问题,提出两种解决方案:Zookeeper分布式锁(追求CP一致性)和Redlock算法(基于多个Redis实例提升可靠性)。文章还讨论了可能遇到的“坑”,如加从节点引发超卖问题、建议Redis节点数为奇数以及持久化策略对锁的影响。最后,从性能优化角度出发,介绍了减少锁粒度和分段锁的策略,并结合实际场景(如下单重复提交、支付与取消订单冲突)展示了分布式锁的应用方法。
1024 3
|
缓存 NoSQL 架构师
Redis批量查询的四种技巧,应对高并发场景的利器!
在高并发场景下,巧妙地利用缓存批量查询技巧能够显著提高系统性能。 在笔者看来,熟练掌握细粒度的缓存使用是每位架构师必备的技能。因此,在本文中,我们将深入探讨 Redis 中批量查询的一些技巧,希望能够给你带来一些启发。
Redis批量查询的四种技巧,应对高并发场景的利器!
|
存储 NoSQL Java
从扣减库存场景来讲讲redis分布式锁中的那些“坑”
本文从一个简单的库存扣减场景出发,深入分析了高并发下的超卖问题,并逐步优化解决方案。首先通过本地锁解决单机并发问题,但集群环境下失效;接着引入Redis分布式锁,利用SETNX命令实现加锁,但仍存在死锁、锁过期等隐患。文章详细探讨了通过设置唯一标识、续命机制等方法完善锁的可靠性,并最终引出Redisson工具,其内置的锁续命和原子性操作极大简化了分布式锁的实现。最后,作者剖析了Redisson源码,揭示其实现原理,并预告后续关于主从架构下分布式锁的应用与性能优化内容。
639 0
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
716 8
|
NoSQL 关系型数据库 Redis
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
这篇文章深入探讨了Redis事务的概念、命令使用、错误处理机制以及乐观锁和悲观锁的应用,并通过WATCH/UNWATCH命令展示了事务中的锁机制。
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀