NoSQL数据库之Redis2

news2024/10/5 19:19:59

Redis 事务

事务的基础概念

关于事务最常见的例子就是银行转账,A 账户给 B 账户转账一个亿 (T1),买一块地盖房子。在这种交易的过程中,有几个问题值得思考:

  • 如何同时保证上述交易中,A账户总金额减少一个亿,B账户总金额增加一个亿? A
  • A账户如果同时在和C账户交易(T2),如何让这两笔交易互不影响? I
  • 如果交易完成时数据库突然崩溃,如何保证交易数据成功保存在数据库中? D
  • 如何在支持大量交易的同时,保证数据的合法性(没有钱凭空产生或消失) ? C

要保证交易正常可靠地进行,数据库就得解决上面的四个问题,这也就是事务诞生的背景,它能解决上面的四个问题,对应地,它拥有四大特性(ACID)。
在这里插入图片描述

  • 原子性(Atomicity): 事务要么全部完成,要么全部取消。 如果事务崩溃,状态回到事务之前(事务回滚)。

  • 隔离性(Isolation): 如果2个事务 T1 和 T2 同时运行,事务 T1 和 T2 最终的结果是相同的,不管 T1和T2谁先结束。

  • 持久性(Durability): 一旦事务提交,不管发生什么(崩溃或者出错),数据要保存在数据库中。

  • 一致性(Consistency): 只有合法的数据(依照关系约束和函数约束)才能写入数据库。

Redis 中的事务

# 标记一个事务块的开始
# 事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行
MULTI

# 执行所有事务块内的命令。
EXEC

# 取消事务,放弃执行事务块内的所有命令。
DISCARD

示例:

SET Jack 10

SET Rose 20

# Jack 给 Rose 转账 5 块钱

# 开启事务
MULTI

DECRBY Jack 5

INCRBY ROSE 5

EXEC

上面的代码演示了事务的使用方式。

(1)开始事务:首先使用 MULTI 命令告诉 Redis:“下面我发给你的命令属于同一事务,你先不要执行,而是把它们暂时存起来”。Redis 回答:“OK”

(2)命令入队:而后我们发送了两个命令来实现相关操作,可以看到 Redis 遵守了承诺,没有执行这些命令,而是返回 QUEUED 表示这两条命令已经进入等待执行的事务队列中了

(3)执行事务:当把所有要在同一事务中执行的命令都发给 Redis 后,我们使用 EXEC 命令告诉 Redis 将等待执行的事务队列中的所有命令按照发送的顺序依次执行。EXEC 命令的返回值就是这些命令的返回值组成的列表,返回值顺序和命令的顺序相同。

(4)如果想要取消事务,则执行 DISCARD 命令。

Redis 保证了一个事务中的所有命令要么都执行,要么都不执行。如果在发送 EXEC 命令前客户端掉线了,则 Redis 会清空事务队列,事务中的所有命令都不会执行。而一旦客户端发送了 EXEC 命令,所有的命令就都会被执行,即使此后客户端断线也没关系,因为 Redis 中已经记录了所有要执行的命令。

除此之外,Redis 的事务还能保证一个事务内的命令依次执行而不被其它命令插入。试想客户端 A 需要执行几条命令,同时客户端 B 发送了一条命令,如果不适用事务,则客户端 B 的命令可能会插入到客户端 A 的几条命令中执行。如果不希望发送这种情况,也可以使用事务。

事务中的错误处理

如果一个事务中的某个命令执行出错,Redis 会怎么处理呢?要回答这个问题,首先需要知道什么原因导致命令执行出错。

(1)语法错误。语法错误指命令不存在或命令参数的个数不对。比如:

MULTI

# 正确的命令
SET key value

# 错误的命令
SET key

ERRORCOMMAND key

EXEC

跟在 MULTI 命令后执行了 3 个命令:

  • 一个正确的命令,成功的加入了事务队列
  • 其余两个命令都有语法错误
    而只要有一个命令有语法错误,执行 EXEC 命令后 Redis 就会直接返回错误,连语法正确的命令也不会执行。

(2)运行错误。运行错误指在命令执行时出现的错误,比如使用散列类型的命令操作集合类型的键,这种错误在实际执行之前 Redis 是无法发现的,所以在事务里这样的命令是会被 Redis 接受并执行的。如果事务里的一条命令出现了运行错误,事务里其它的命令依然会继续执行

MULTI

SET key 1

SADD key 2

SET key 3

EXEC

Redis 事务没有关系数据库事务提供的回滚(rollback)功能。为此开发者必须在事务执行出错后自己收拾剩下的摊子(将数据库复原回事务执行前的状态等)。

不过由于 Redis 不支持回滚功能,也使得 Redis 在事务上可以保持简洁和快速。此外回顾刚才提到的会导致事务执行失败的两种错误,其中语法错误完全可以在开发时找出并解决,另外如果能够很好的规划数据库的使用,是不会出现如命令与数据类型不匹配这样的运行时错误的。

事务中的 WATCH 命令

关于 WATCH 命令,我们来一个生活中的例子比较好理解。

假设我的银行卡有 100 元,此时我去商店买东西

# 开启事务
MULTI

# 假设里面有 100 元
SET balance 100

# 拿了瓶水
SET balance 3

# 拿了包烟
SET balance 20

我的银行卡除了我自己消费使用,还绑定了我媳妇儿的支付宝,如果我在消费的时候,她也消费了会怎么样?

# 开启事务
MULTI

# 买了 10 斤苹果
SET balance 100

EXEC

这时候我媳妇在超市直接刷了 100,此时余额不足的我还在挑口香糖…

针对于上面的场景,我们可以使用 Redis 事务中提供的 WATCH 功能来解决这个问题。

WATCH 定义:监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

WATCH 相关命令如下:

# 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
WATCH key [key ...]

# 取消 WATCH 命令对所有 key 的监视。
# 如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行 UNWATCH 了。
UNWATCH

SET balance 100

WATCH balance

DECRBY balance 30

MULTI

DECRBY balance 10

EXEC

GET balance # 70

如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令被执行了的话,那么会自动取消 WATCH。

如果需要手动停止 WATCH 则可以可以使用 UNWATCH 命令,UNWATCH 命令会取消 WATCH 命令对所有 key 的监视。

参考链接

  • https://zhuanlan.zhihu.com/p/43493165
  • https://xie.infoq.cn/article/84baa7fa9c2c3d3698a601def

Redis持久化

Redis 的强劲性能很大程度上是由于其将所有数据都存储在内存中,然而当 Redis 重启或宕机后,所有存储在内存中的数据就会丢失。在一些情况下,我们会希望 Redis 在重启后能够保证数据不丢失。

这时我们希望 Redis 能将数据从内存中以某种形式同步到硬盘中,使得重启后可以根据硬盘中的记录恢复数据。这一过程就是持久化。

Redis 提供了两种持久化方案:

  • RDB 持久化,根据指定的规则“定时”将内存中的数据存储在硬盘上,在重启之后读取硬盘上的 .rdb 快照文件将数据恢复到内存中。
  • AOF 持久化:AOF 持久化记录服务器执行的所有写操作命令形成 .aof 日志文件保存到硬盘中,并在服务器启动时,通过重新执行这些命令来还原数据集。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计Django的毕业生就业系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

蜂鸟E203学习笔记(四)——取指

1.1 取值概述 1.1.1 如何快速取指 首先要保证存储器的读延时足够小,通常使用指令紧耦合存储器(ITCM)和指令缓存器(ICache)。 ITCM通常使用离处理核很近的SRAM因此实现极短的延时。但是没有过大的存储空间&#xff0…

社区系统项目复盘-2

文章目录登录模块注册登录账号设置登录模块 重要知识点: ThreadLocal,Hostholder采用Threadlocal持有用户信息,用于代替session对象 ThreadLocal采用线程隔离的方式存放数据,可以避免多线程之间出现数据访问冲突。ThreadLocal提…

小程序全局配置文件以及常用配置项

一、window常用配置 1.小程序根目录下的app.json文件时小程序的全局配置文件。常用配置项如下: ① pages 记录当前小程序所有页面的存放路径 ② window 全局设置小程序窗口的外观 ③ tabBar 设置小程序底部的tabBar效果 ④ style 是否启用新版的组件样式 …

【Spring项目中的Service理解】

目录 1. Spring项目中的核心组成部分 2. Spring项目中的Service 2.1 Service的功能作用 2.2 Service的实现 1. Spring项目中的核心组成部分 项目的核心组成部分图解: 2. Spring项目中的Service 2.1 Service的功能作用 Service是项目中用于处理业务逻辑的&#x…

【学习笔记66】JavaScript的深浅拷贝

一、赋值 只要是引用数据类型, 那么在赋值的时候, 就是引用地址的传递// 赋值:字符串const s1 123;let s2 s1; // 赋值console.log(s2 s1); // trues2 456;console.log(s1); // 123console.log(s2); // 456 let o1 { a: 1 };let o2 o1; // 赋值console.log…

【iOS】—— GET和POST以及AFNetworking框架

GET和POST以及AFNetworking框架 文章目录GET和POST以及AFNetworking框架GET和POSTGET和POST区别GETGET请求步骤GET请求代码POSTPOST请求步骤POST请求代码AFNetworking简介添加头文件GETGET方法GET方法参数GET方法代码样例POSTPOST方法第一种:第二种:先来…

[附源码]计算机毕业设计springboot防疫物资捐赠

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

springboot+jsp学生成绩查询考务系统

众所周知,现代信息技术是现代教育技术的基础和核心,培养和创新型的人才,必须依靠现代教育技术。从这一层意义上讲,我们说掌握一定的计算机应用技能已经成为国家未来的合格建设者的必备素质,所以现在在大学中对非计算机…

Huggingface的介绍,使用(CSDN最强Huggingface入门手册)

Huggingface的介绍,使用(CSDN最强Huggingface入门手册)返回论文和资料目录 1.Huggingface的简介 Huggingface即是网站名也是其公司名,随着transformer浪潮,Huggingface逐步收纳了众多最前沿的模型和数据集等有趣的工…

代码源每日一题div1 DP 数组划分

数组划分 - 题目 - Daimayuan Online Judge 题意: 思路: 关于位运算的最大值,只需要按位去贪心即可,即从高位向低位贪心,答案一定是1111000的形式 那么我们去枚举这个1和0的分界线在哪就好了 对于一个确定好的分界…

模板学堂丨DataEase用户操作日志分析大屏

DataEase开源数据可视化分析平台于2022年6月正式发布模板市场(https://dataease.io/templates/)。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板,方便用户根据自身的业务需求和使用场景选择对应的仪表板模板,并…

基于FPGA的ALU计算器verilog实现

欢迎订阅《FPGA学习入门100例教程》、《MATLAB学习入门100例教程》 目录 一、理论基础 二、核心程序 三、测试结果 一、理论基础 Verilog HDL是一种硬件描述语言,以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式…

粒子群算法查找函数最小值

实现 函数 F01、F06 的优化测试 以下内容是现有算法的运行结果、调参分析、及代码实现,用于给其他人提供参考,懒得改了hh 1. 运行结果 参数 w 0.5 (可更改) c1 2.0 (可更改) c2 2.0 (可更改&…

2.每天进步一点点-Python爬虫需要了解一下基础的web相关内容

14天学习训练营导师课程: 杨鑫《Python 自学编程基础》 杨鑫《 Python 网络爬虫基础》 杨鑫《 Scrapy 爬虫框架实战和项目管理》 文章目录1.网络请求过程1.1通过 URL 查找服务器 IP1.2三次握手建立 TCP 连接1.3发送 HTTP 请求1.4服务器响应请求1.5浏览器解析 HTML1.…

21年-自研-笔试题

目录背景题目1、Object的常用方法2、 和 equals 的区别是什么?equals3、以下代码的运行结果4、以下代码的运行结果5、String, StringBuilder,StringBuffer6、ArrayList和LinkedList7、一些常用的线程安全的集合类8、以下代码的运行结果9、完成下面的代码…

Java环境准备——JDK下载和安装、IDEA下载和安装

一、JDK下载及安装 1、必要性:JDK是整个Java开发的核心。 2、下载网址:Java Downloads | Oracle 3、选择下载JDK17的原因:JDK17 是Java的长期支持版本。 4、下载到本地后,双击进行安装,然后点击下一步,安…

AI物品分类识别管理系统uniapp源码带文档教程

技术架构 技术框架:SpringBoot2 Mysql5.7 Mybatis-Plus uniapp Swagger2 RuoYi-fast swagger-bootstrap-ui 运行环境:jdk8 IntelliJ IDEA maven 宝塔面板 百度智能云平台服务 本地api接口端搭建教程 后端需要准备相关的IDE和JDK8开发环境 , 前…

GIT技巧

目录 基础命令 commit 、branch merge rebase 高级特性 自由修改提交树 cherry-pick rebase 远程仓库命令 基础命令 commit 、branch Git Commit Git 仓库中的提交记录保存的是你的目录下所有文件的快照,就像是把整个目录复制,然后再粘贴一样…

Linux内核中ideapad-laptop.c文件全解析6

接前一篇文章《Linux内核中ideapad-laptop.c文件全解析5》,地址为: Linux内核中ideapad-laptop.c文件全解析5_蓝天居士的博客-CSDN博客 上一篇详细分析了ideapad_debugfs_init,本篇详细分析ideapad_input_init。 ideapad_input_init ideap…