redis--事务

news/2025/3/14 17:18:53/

redis事务

在Redis中,事务是一组原子性操作的集合,它们被一起执行,要么全部执行成功,要么全部回滚。虽然Redis的事务并不遵循传统数据库的ACID特性,但它仍然提供了一种将多个命令打包成一组执行的机制,适用于需要保持一系列操作的一致性的场景。

常见命令

命令描述
MULTI开启一个事务,标记事务块的开始
EXEC执行事务中的所有命令,并将结果返回
DISCARD取消当前事务,放弃事务中的所有命令
WATCH监视一个或多个键,如果在事务执行前键被修改,事务将被中断
UNWATCH取消对所有键的监视
QUEUED在事务块中的每个命令执行后返回的标识

事务流程

开始事务:使用MULTI命令标记一个事务块的开始。
命令入队:在MULTI之后,所有的命令都不会立即执行,而是被放入一个队列中,每个命令都会返回一个QUEUED的响应。
执行事务:使用EXEC命令触发事务,一并执行事务中的所有命令,并返回一个数组作为结果。如果事务中有语法错误或者类型错误的命令,那么EXEC会返回一个错误,并且不执行任何命令。如果事务中有运行时错误的命令,那么EXEC会跳过这些错误命令,继续执行其他正常的命令。

事务冲突

在Redis中,事务冲突通常指的是在执行事务过程中,多个客户端对相同的键进行修改,从而引发数据不一致的情况。这种情况可能导致事务的结果与预期不符,因为不同客户端可能会在事务中同时修改相同的数据,而事务并不具备真正的隔离性和锁机制,所以可能导致数据冲突。

举个例子,假设有两个客户端在并发地进行购买商品的操作,每个客户端都会从库存中减少相应数量的商品。如果两个客户端同时在事务中减少库存,那么可能会出现如下冲突:

  1. 客户端A读取库存为10,开始执行事务。
  2. 客户端B同时读取库存也为10,开始执行事务。
  3. 客户端A将库存减少3,变成7。
  4. 客户端B将库存减少2,变成8。

在这种情况下,两个客户端的事务冲突,导致库存的最终结果不是预期的。这就是事务冲突引发的问题,可能导致数据不一致性。

为了避免事务冲突,Redis提供了WATCH命令,可以在事务执行前监视一个或多个键,如果在事务执行前有其他客户端对这些键进行了修改,事务会被中断,这样可以减少事务冲突的可能性。但是需要注意,WATCH并不能完全解决事务冲突问题,因为仍然可能在EXEC执行时发生冲突。

乐观锁和悲观锁

乐观锁

乐观锁是一种较为轻量级的并发控制机制,它假定在大多数情况下,事务之间不会发生冲突。在 Redis 中,乐观锁通常通过使用版本号或时间戳来实现。当一个客户端想要修改一个键的值时,它会先获取当前键的版本号或时间戳,然后在修改完成后再次检查版本号或时间戳是否仍然一致。如果一致,说明期间没有其他客户端修改过该键的值,操作可以被提交。如果不一致,说明期间有其他客户端修改了该键的值,操作可能会失败或需要重试。

优点:

  • 适用于多读少写的场景,因为大部分时间数据冲突较少。
  • 不需要长时间的锁定,提高了系统的并发性能。

缺点:

  • 当冲突发生时,需要重试操作,可能会增加系统开销。
  • 无法解决高并发下的复杂冲突。

悲观锁

悲观锁是一种相对较重的并发控制机制,它假定事务之间可能会发生冲突,因此在访问数据之前会对数据进行锁定,以防止其他事务对其进行修改。在 Redis 中,悲观锁通常使用 WATCH 命令来实现,它可以监视一个或多个键,如果在事务执行期间这些键的值发生了变化,事务将被回滚。

优点:

  • 可以确保数据的一致性,适用于复杂的事务场景。
  • 避免了操作冲突,无需重试。

缺点:

  • 长时间的锁定可能降低系统的并发性能。
  • 需要耗费更多的系统资源。

乐观锁和悲观锁的对比:

  1. 性能开销: 乐观锁的性能开销较低,因为它不会长时间地锁定数据,而是在操作时检查冲突。悲观锁在锁定数据的同时,会对系统的并发性能产生一定的影响。

  2. 适用场景: 乐观锁适用于多读少写的场景,因为它假定冲突较少。悲观锁适用于复杂的事务场景,需要确保数据的一致性。

  3. 冲突处理: 乐观锁在发生冲突时需要进行重试操作,而悲观锁可以避免操作冲突,但可能会造成长时间的等待。

  4. 并发性能: 乐观锁可以提高系统的并发性能,因为它不会长时间锁定数据。悲观锁可能会降低系统的并发性能,因为它需要长


http://www.ppmy.cn/news/1048995.html

相关文章

SpringCloud全家通新人入门手册

一、架构图 二、springCloud全家桶组件库 三、Spring Cloud 实战项目全景规划 四、技术选型 第一阶段:搭建基础的微服务功能,实现微服务之间的通信; 1、服务治理:服务治理的重点是搭建基础的跨服务调用功能。我会把用户服务、优…

Python实操手动抛出异常且用except捕获

try:scroe int(input(输入一个分数))if 1 < scroe < 100:print(分数为, scroe)else:raise Exception(分数错了) except Exception as e:print(e)

Mac下Jmeter安装及基本使用

本篇文章只是简单的介绍下Jmeter的下载安装和最基本使用 1、初识Jmeter 前一段时间客户端app自测的过程中&#xff0c;有偶现请求某个接口返回数据为空的问题&#xff0c;领导让我循环100次请求这个接口&#xff0c;看看有没有结果为空的问题。听同事说有Jmeter的专业测试工具…

监控 FTP 服务器

文件传输协议 &#xff08;FTP&#xff09; 用于在 TCP/IP 网络中的服务器和客户端之间传输文件&#xff0c;它是一种标准协议&#xff0c;广泛用于在各个垂直行业的组织之间从集中位置存储和分发数据。FTP协议的其他一些安全版本如下&#xff1a; SSH 文件传输协议 &#xff…

性能比较 - Spring Boot 应用程序中的线程池与虚拟线程 (Project Loom)

本文比较了 Spring Boot 应用程序中的不同请求处理方法&#xff1a;ThreadPool、WebFlux、协程和虚拟线程 (Project Loom)。 在本文中&#xff0c;我们将简要描述并粗略比较可在 Spring Boot 应用程序中使用的各种请求处理方法的性能。 高效的请求处理在开发高性能后端…

【Apollo】自动驾驶感知——毫米波雷达

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

依赖预构建与静态资源处理

依赖预构建 vite是一个基于浏览器原生ES-Module的前端构建工具。 当你首次启动vite的时候&#xff0c;vite会在本地加载你的站点之前预构建项目依赖。 原因&#xff1a; CommonJS和UMD兼容性&#xff1a;在开发阶段中&#xff0c;Vite的开发服务器将所有的代码视为原生ES模块。…

[Docker] Portainer + nginx + AList 打造Docker操作三板斧

Portainer : Docker容器图形化管理系统nginx: 反向代理利器AList: 文件管理系统 1. 安装 ##### portainer ##### # 拉取镜像 portainer 注: ce 社区版 ee 企业版 原项目(portainer/portainer)已弃用 docker pull portainer/portainer-ce # 运行容器 docker run -d --name por…