Redis --- redis事务和分布式事务锁

redis事务基本实现

Redis 可以通过 MULTI,EXEC,DISCARD 和 WATCH 等命令来实现事务(transaction)功能。

> MULTI
OK
> SET USER "Guide哥"
QUEUED
> GET USER
QUEUED
> EXEC
1) OK
2) "Guide哥"

使用 MULTI命令后可以输入多个命令。Redis 不会立即执行这些命令,而是将它们放到队列,当调用了EXEC命令将执行所有命令。过程如下:

  1. 开始事务(MULTI)。
  2. 命令入队(批量操作 Redis 的命令,先进先出(FIFO)的顺序执行)。
  3. 执行事务(EXEC)。

你也可以通过 DISCARD 命令取消一个事务,它会清空事务队列中保存的所有命令。

> MULTI
OK
> SET USER "Guide哥"
QUEUED
> GET USER
QUEUED
> DISCARD
OK

WATCH 命令用于监听指定的键,当调用 EXEC 命令执行事务时,如果一个被 WATCH 命令监视的键被修改的话,整个事务都不会执行,直接返回失败。

> WATCH USER
OK
> MULTI
> SET USER "Guide哥"
OK
> GET USER
Guide哥
> EXEC
ERR EXEC without MULTI

Redis 官网相关介绍 https://redis.io/topics/transactions 如下:

但是,Redis 的事务和我们平时理解的关系型数据库的事务不同。我们知道事务具有四大特性: 1. 原子性,2. 隔离性,3. 持久性,4. 一致性。

  • 原子性(Atomicity): 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  • 隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  • 持久性(Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
  • 一致性(Consistency): 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;

关于 redis 没有事务回滚?

首先原子性的定义:事务中的命令要么全部被执行,要么全部都不执行。

然后再看官方文档关键段:

Redis commands can fail during a transaction, but still Redis will execute the rest of the transaction instead of rolling backRedis 在事务失败时不进行回滚,而是继续执行余下的命令

我根据Redis文档理解,认为事务过程中失败有两种可能

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令中用在了错误类型的键上面,所以如果在生产环境中你使用的正常命令,那么在 Redis 事务中,是不会出现错误而导致回滚的。

来自文档:Redis commands can fail only if called with a wrong syntax...

  • 事务执行一半,Redis宕机。如果 Redis 服务器因为某些原因被管理员杀死,或者遇上某种硬件故障,那么可能只有部分事务命令会被成功写入到磁盘中。如果 Redis 在重新启动时发现 AOF 文件出了这样的问题,那么它会退出,并汇报一个错误。使用redis-check-aof程序可以修复这一问题:它会移除 AOF 文件中不完整事务的信息,确保服务器可以顺利启动

注意:

  • 若在事务队列中存在命令性错误(类似于java编译性错误),则执行EXEC命令时,所有命令都不会执行
  • 若在事务队列中存在语法性错误(类似于java的1/0的运行时异常),则执行EXEC命令时,其他正确命令会被执行,错误命令抛出异常。

Redis 官网也解释了自己为啥不支持回滚。简单来说就是 Redis 开发者们觉得没必要支持回滚,这样更简单便捷并且性能更好(回滚还需要解决回滚事务覆盖的问题)。Redis 开发者觉得即使命令执行错误也应该在开发过程中就被发现而不是生产过程中。

你可以将 Redis 中的事务就理解为 :Redis 事务提供了一种将多个命令请求打包的功能。然后,再按顺序执行打包的所有命令,并且不会被中途打断。

分布式事务锁

基础知识:

  • 分布式:简单来说就是将业务进行拆分,部署到不同的机器来协调处理,保证高性能。比如用户在网上买东西,大致分为:订单系统、库存系统、支付系统、、、、这些系统共同来完成用户买东西这个业务操作。
  • 集群:同一个业务,通过部署多个实例来完成,保证应用的高可用。如果其中某个实例挂了,业务仍然可以正常进行,通常集群和分布式配合使用。来保证系统的高可用、高性能。
  • 分布式事务:按照传统的系统架构,下单、扣库存等等,都是在单机系统中, 这一系列的操作都是一个数据库中完成的,也就是说保证了事务的ACID特性。如果在分布式应用中就会涉及到跨应用、跨库。这样就涉及到了分布式事务,就要考虑怎么保证这一系列的操作要么都成功要么都失败。保证数据的一致性。
  • 分布式锁:因为资源有限,要通过互斥来保持一致性,比如下订单的数据库操作和支付的数据库操作就是一个保证互斥性, 不能同时去执行, 不然那就会出现一旦支付出现失败, 那么下订单也得重新下订单, 这就不合理了, 所以引入分布式事务锁。

分布式事务锁:

  • 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。
  • 简单来说就是好几个节点访问一个资源, 那我就是使用额外的锁机制互斥的只让其中一个能进行访问

核心思想:

  • 在被保护的redis节点加一把锁, 让这把锁和被保护的redis节建立直接映射
  • 在访问这个redis之前都去看看这把锁在不在
  • 如果不存在锁,说明没有客户端使用,可以执行任务,执行完毕,解锁,删除锁 (并且要保证判断有无锁和加锁是原子操作)
  • 如果存在锁,则认为有其他客户端在使用,等待锁消失

基本操作:

  • Redis中可以使用SETNX命令实现分布式锁,SETNX——SET if Not exists(如果不存在,则设置)
setnx key value
  • 如果需要解锁,使用 del key 命令就能释放锁

分布式锁存在的问题,解决方案

Q1:当一个客户端上锁之后服务宕机,由于锁是他上的只有他可以进行redis访问的,别人无法访问,所以导致锁无法被删除.

A1:给锁设置一个过期时间,可以通过两种方法实现:通过命令 “setnx 键名 过期时间 “;或者通过设置锁的expire(失效)时间,让Redis去删除锁。

Q2:当一个客户端设置了锁的失效时间, 但是这个客户端并没有宕机, 只是真的需要那么多时间来进行操作,也就是任务执行过长,超过过期时间。

A2:实际是通过客户端的一个守护线程,大概时间快到的时间给线程续命。

Q3:任务执行造成死循环,会造成无限续命

A3:设置最大续命时间, 或者设置最大续命次数

巨人的肩膀:

https://snailclimb.gitee.io/javaguide/#/docs/database/Redis

https://blog.csdn.net/Shangxingya/article/details/111622234

最后编辑于:2024-09-22 09:33:52


喜欢的朋友记得点赞、收藏、关注哦!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/432273.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java数据库连接jdbc

Java数据库连接jdbc 导入java包 1、根目录,新建一个lib目录(Dire) 2、将jar包放入lib目录下 3、File -> Project Structure(项目结构) 4、Libraries-> ->java->找到项目的lib目录 5、Apply->OK使用JD…

navicat无法连接远程mysql数据库1130报错的解决方法

出现报错:1130 - Host ipaddress is not allowed to connect to this MySQL serve navicat,当前ip不允许连接到这个MySQL服务 解决当前ip无法连接远程mysql的方法 1. 查看mysql端口,并在服务器安全组中放开相应入方向端口后重启服务器 sud…

二叉树的基本概念(下)

文章目录 🍊自我介绍🍊二叉树的分类满二叉树完全二叉树 🍊二叉树的存储顺序存储[完全二叉树]链式存储 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞关注评论收藏(一键四连)哦~ &#x1f34…

顶点缓存对象(VBO)与顶点数组对象(VAO)

我们的顶点数组在CPU端的内存里是以数组的形式存在,想要GPU去绘制三角形,那么需要将这些数据传输给GPU。那这些数据在显存端是怎么存储的呢?VBO上场了,它代表GPU上的一段存储空间对象,表现为一个unsigned int类型的变量,GPU端内存对象的一个ID编号、地址、大小。一个VBO对…

利用探空站数据(怀俄明和IGRA)和ERA5计算ZTD、ZHD和ZWD

1.有关 Matlab 获取代码关注咸鱼获取: 怀俄明探空站数据解算PWV和Tm 怀俄明多线程下载探空站数据(包括检查和下载遗漏数据的代码) 对IGRAv2进行质量控制得到PWV和Tm的 matlab 代码 算 IGRAv2 探空站的 Tm 和 PWV 提取探空站 IGRAv2 全部数…

单片机串口AT指令操作SIM800、900拨打电话

文章目录 一、前言1.1 功能简介1.2 拨打电话功能的应用场景1.3 SIM900A与SIM800C模块介绍1.4 原理图 三、模块调试3.1 工具软件下载3.2 准备好模块3.3 串口调试助手的设置3.4 初始化配置3.5 拨打电话的测试流程 四、代码实现4.1 底层的命令发送接口4.2 底层数据接收接口4.3 检测…

基于Next.js和TailwindCss的TailwindCss

最近在研究 Next.js 和 TailwindCss ,这两天没事的时候就搞了一个 c。 目前工具部署在 Vercel ,欢迎各位体验(能提出意见更好嘿嘿) 体验地址: https://icon.999872.xyz/ 图片预览 👇

MySQL Performance Schema 详解及运行时配置优化

引言 MySQL 的 Performance Schema 是一套性能监控与诊断工具,帮助开发者和数据库管理员收集、分析 MySQL 实例的运行状态,找出性能瓶颈并进行优化。通过 Performance Schema,我们能够监控不同的内部事件、线程、会话、语句执行等关键性能指…

LabVIEW界面输入值设为默认值

在LabVIEW中,将前面板上所有控件的当前输入值设为默认值,可以通过以下步骤实现: 使用控件属性节点:你可以创建一个属性节点来获取所有控件的引用。 右键点击控件,选择“创建” > “属性节点”。 设置属性节点为“D…

Pandas和Seaborn可视化详解

1.Pandas绘图-单变量 概述 pandas库是Python数据分析的核心库 它不仅可以加载和转换数据,还可以做更多的事情:它还可以可视化 pandas绘图API简单易用,是pandas流行的重要原因之一 可视化小技巧: 如果是类别型 柱状 饼图 (类别相对较少 5-…

灵办AI搜索引擎和文档总结工具

前言—— 在信息爆炸的时代,如何高效地获取和处理知识成为了每个人面临的挑战。随着人工智能技术的迅猛发展,本文将深入探讨这一创新工具的功能与优势,以及如何在日常生活和工作中充分利用它,开启智能化的信息获取新篇章。 点击…

金属增材制造咋突破?纳米纹理粉末如何助力金属增材制造?

大家好,今天我们来了解一篇金属增材制造文章——《High absorptivity nanotextured powders for additive manufacturing》发表于《Science Advances》。金属增材制造在医疗、航空航天等领域,它潜力巨大,但目前可打印的金属材料有限&#xff…

握手传输 状态机序列检测(记忆科技笔试题)_2024年9月2日

发送模块循环发送0-7,在每个数据传输完成后,间隔5个clk,发送下一个 插入寄存器打拍处理,可以在不同的时钟周期内对信号进行同步,从而减少亚稳态的风险。 记忆科技笔试题:检测出11011在下一个时钟周期输出…

PowerPoint技巧:将幻灯片里的图片背景设置为透明

在PPT中添加了图片,想要将图片中的背景设置为透明或者想要抠图,有什么方法吗?今天分享两个方法。 方法一: 添加图片,选中图片之后,点击【图片格式】功能,点击最左边的【删除背景】 PPT会自动帮…

vue3扩展echart封装为组件库-快速复用

ECharts ECharts,全称Enterprise Charts,是一款由百度团队开发并开源,后捐赠给Apache基金会的纯JavaScript图表库。它提供了直观、生动、可交互、可个性化定制的数据可视化图表,广泛应用于数据分析、商业智能、网页开发等领域。以…

Distilabel合成数据生成框架简明教程

Distilabel 是一个用于合成数据和 AI 反馈的框架,适用于需要基于经过验证的研究论文的快速、可靠和可扩展的管道的工程师。 NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 -…

Webpack教程-概述

什么是Webpack Webpack是一个静态资源打包工具。它以一个或多个文件作为打包入口,将整个项目所有的文件编译组合成一个或多个文件进行输出。(输出的文件即编译好的文件,就可以在浏览器上运行) Webpack官网 核心概念 entry (入口) entiry 指webpack…

企业源代码怎么保护?2024年最新推荐10款源代码加密软件

在现代企业中,源代码是核心资产之一,保护源代码安全已成为企业管理中的重中之重。源代码的泄露不仅会导致企业知识产权的流失,还可能带来竞争对手的复制和攻击。因此,采用强大的源代码加密工具已成为许多企业的必要措施。2024年&a…

深入探索 RUM 与全链路追踪:优化数字体验的利器

作者:梅光辉(重彦) 背景介绍 随着可观测技术的持续演进,多数企业已广泛采用 APM、Tracing 及 Logging 解决方案,以此强化业务监控能力,尤其在互联网行业,产品的体验直接关系着用户的口碑&…

Adaptive Graph Contrastive Learning for Recommendation

Adaptive Graph Contrastive Learning for Recommendation(KDD23) 源码: https://github.com/HKUDS/AdaGCL 摘要 图神经网络(GNNs)最近作为推荐系统中的有效协同过滤(CF)方法受到关注。基于GNN…