MySQL和Redis事务的比较(图文)

本篇文章给大家带来的内容是关于mysql和redis事务的比较(图文),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

简言:一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

从标题来看,既然都是事务,那之间有什么区别?来一一解开,先从两个数据库说去。

MySQL 属于 关系型数据库 , Redis 属于 非关系型数据库,两者对事务有着不同的解释。

(相关推荐:MySQL教程,Redis教程)

Redis

[1] Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:

批量操作在发送 EXEC 命令前被放入队列缓存。收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

一个事务从开始到执行会经历以下三个阶段:

开始事务。命令入队。执行事务。

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

操作错误

看着有点儿绕口,那就实际执行一下 看一下结果。

127.0.0.1:6379> multiOK127.0.0.1:6379> set tr_1 233QUEUED127.0.0.1:6379> lpush tr_1 666QUEUED127.0.0.1:6379> set tr_2 888QUEUED127.0.0.1:6379> exec1) OK2) (error) WRONGTYPE Operation against a key holding the wrong kind of value3) OK

在上面的事务中,设置了一个 key 为 tr_1 的字符串数据,然后又通过 lpush 来添加元素,这很明显是错误的操作方式,当我们提交事务候出现了一个操作错误,这时候我们来看看 tr_1 的值是什么。

127.0.0.1:6379> get tr_1"233"

通过 get 命令来的tr_1 内容还是 233 ,并没有变,那再看一下其他的。

127.0.0.1:6379> keys *1) "tr_2"2) "tr_1"127.0.0.1:6379> get tr_2"888"127.0.0.1:6379>

这里可以看到 tr_2 存在,并打印了值,这时候我们发现,即使出现了操作错误 ,但是错误并没有致使执行停止,错误之后的语句也执行了并成功执行,似乎符合上面提到的 中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

语法错误

NO~,这时候还有另外一种情况 语法错误

127.0.0.1:6379> multiOK127.0.0.1:6379> set tr_1 233QUEUED127.0.0.1:6379> lpush tr_1 666QUEUED127.0.0.1:6379> set(error) ERR wrong number of arguments for 'set' command127.0.0.1:6379> set 233(error) ERR wrong number of arguments for 'set' command127.0.0.1:6379> set tr_2 888QUEUED127.0.0.1:6379> exec(error) EXECABORT Transaction discarded because of previous errors.127.0.0.1:6379> keys *(empty list or set)

当我们执行到 set时没有给任何参数,第二次执行时故意少给了一个参数。可以看到报了 语法错误,最后提交事务,也告诉了我们事务因为错误被丢失了,接着用 keys *检索发现确实如此。

文档释义

这里可以官方文档中提到的

Errors inside a transaction// 在执行过程中 可能会遇到两种错误命令错误。During a transaction it is possible to encounter two kind of command errors:// 1.命令无法进入队列 ,比如 :参数数量错误,命令名错误…,或者某些关键错误 如内存不足A command may fail to be queued, so there may be an error before EXEC is called. For instance the command may be syntactically wrong (wrong number of arguments, wrong command name, …), or there may be some critical condition like an out of memory condition (if the server is configured to have a memory limit using the maxmemorydirective).// 2. 对键进行错误的操作 如上面的 对字符串使用 lpushA command may fail after EXEC is called, for instance since we performed an operation against a key with the wrong value (like calling a list operation against a string value).// 客户端检查键入的命令,大多数时候会在调用 exec 前发现第一类错误,如果命令执行返回来 QUEUED 则表示命令正常进入队列,否则错误,大多数情况下客户端会终止放弃这个事务。Clients used to sense the first kind of errors, happening before the EXEC call, by checking the return value of the queued command: if the command replies with QUEUED it was queued correctly, otherwise Redis returns an error. If there is an error while queueing a command, most clients will abort the transaction discarding it.

关于 Redis 暂时看到这里 接下来看到 MySQL

MySQL

众所周知,MySQL 只有 InnoDB 引擎支持 事务,在启用 MySQL 事务之前需要先停掉自动提交

测试表结构 user

列 类型 注释

idint(11) 自动增量主键IDmoneyint(11) [0]金钱titlevarchar(500) NULL称呼

在这里来模拟一个转账的操作:A给B转100元。

Calliper 文档对比神器 Calliper 文档对比神器

文档内容对比神器

Calliper 文档对比神器 28 查看详情 Calliper 文档对比神器

步骤解析 A+100 元,B -100元,即两步虽然很简单,简单走一下流程。

786250041-5c9dedec637a1_articlex.png

可以看到,没有问题,那么我们从中人为的制造一些问题呢?

操作错误

列类型注释idint(11) 自动增量
moneyint(11) unsigned [0]
titlevarchar(500) NULL

这里我们把 money 字段变成了无符号,即不能小于 0,并且,调整数据库中的数据如下。

`SELECT * FROM `user` LIMIT 50` (0.000 秒)
修改 id money title

编辑110000A编辑20B

接着执行下面的 SQL

select version();SET AUTOCOMMIT=0;begin;select * from user where title in ('A','B') for update;update user set  money = money + 1000 where title = 'A';update user set money = money - 1000 where title = 'B';select * from user where title in ('A','B');commit;

1496933587-5c9dee0d04153_articlex.png

问题出现了,这里报出了错误,但是可以看到 前面的 SQL 已经是已执行的了,结果已经发生了变化,从这里看,似乎和 Redis 的处理差不多,除了错误之后语句继续执行。但是 值的注意的是, 在我们实际开发中,这种情况程序会直接抛出异常,以供我们在 catch 块中执行 rollback ,以回滚操作确保数据完整,即使是单独使用 MySQL 命令行 我们也可以用存储过程来对异常进行回滚。

语法错误

刚刚看到 Redis 当遇到 语法错误 时会自动丢弃事务,阻止提交,那 MySQL 呢?

2797577650-5c9dee2763b3d_articlex.png

答案:不会,MySQL 在顺序执行时,如果未对异常进行处理,总会将成功执行的的提交,而不会触发自动终止,但是我们可以在程序执行时进行放弃提交。

Redis 为什么没有回滚?

Redis 的官方文档给出了这样的解释

// 只有在使用错误的语法调用时才会失败Redis命令(并且在命令排队期间无法检测到问题),或者对于持有错误数据类型的键,Redis命令可能会失败:这意味着实际上失败的命令是编程错误的结果,以及在开发过程中很可能检测到的一种错误,而不是在生产中。

Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.

// Redis内部简化且速度更快,因为它不需要回滚的能力。

Redis is internally simplified and faster because it does not need the ability to roll back.

总结

数据库    自动回滚条件 操作错误 语法错误

MySQL✖✖Redis✖✔

但是 MySQL 支持手动回滚,实际开发过程中可以自行手动对已提交的操作进行回滚操作,更加友好。

以上就是MySQL和Redis事务的比较(图文)的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/373260.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
swoole监测客户端是否断线的方法
上一篇 2025年11月6日 08:45:50
上市大涨190.2% 黄山谷捷成功登陆创业板
下一篇 2025年11月6日 08:45:54

相关推荐

  • 修改MySQL字段collation属性修复排序乱码问题

    mysql字段排序乱码问题通常由字符集和排序规则设置不当引起。要解决此问题,首先查看当前字段collation设置,可用show create table或show full columns命令确认;其次根据需求修改字段的collation,仅改排序规则可用alter table … m…

    2026年10月6日
    000
  • Java实现多级缓存架构的详细设计与性能优化方案

    Java实现多级缓存架构的详细设计与性能优化方案Java实现多级缓存架构的详细设计与性能优化方案Java实现多级缓存架构的详细设计与性能优化方案Java实现多级缓存架构的详细设计与性能优化方案

    多级缓存架构通过分层存储提升性能并降低数据库压力。1. 其基本结构由本地缓存(如caffeine)和远程缓存(如redis)组成,访问流程依次为本地缓存→远程缓存→数据库。2. java中可通过caffeine实现本地缓存、spring data redis实现远程缓存,并封装统一访问接口。3. 性…

    2026年10月6日 • 用户投稿
    000
  • MySQL和PostgreSQL:数据安全与备份策略

    mysql和postgresql:数据安全与备份策略 引言:在现代社会中,数据成为了企业和个人生活中不可或缺的一部分。对于数据库管理系统来说,数据安全与备份策略是至关重要的,既能保护数据免受丢失或损坏,也能确保恢复数据的可靠性和完整性。本文将重点讨论MySQL和PostgreSQL两种主流关系型数据…

    2026年10月6日
    100
  • MySQL和PostgreSQL:性能对比与优化技巧

    mysql和postgresql:性能对比与优化技巧 在开发web应用程序时,数据库是不可或缺的组成部分。而在选择数据库管理系统时,MySQL和PostgreSQL是两个常见的选择。他们都是开源的关系型数据库管理系统(RDBMS),但在性能和优化方面有一些不同之处。本文将比较MySQL和Postgr…

    2026年10月6日
    100
  • 如何使用MySQL中的TIME_FORMAT函数将时间格式化为特定的字符串

    如何使用mysql中的time_format函数将时间格式化为特定的字符串 MySQL是一个广泛使用的关系型数据库管理系统,它提供了丰富的函数和操作符来处理数据。在MySQL中,有一个非常有用的函数,即TIME_FORMAT函数,可以将时间按照指定的格式进行格式化并返回一个字符串。 TIME_FOR…

    2026年10月6日
    000
  • 如何用SELECT语句精确查询特定列?星号(*)通配符的使用场景与风险有哪些?

    如何用SELECT语句精确查询特定列?星号(*)通配符的使用场景与风险有哪些?如何用SELECT语句精确查询特定列?星号(*)通配符的使用场景与风险有哪些?如何用SELECT语句精确查询特定列?星号(*)通配符的使用场景与风险有哪些?如何用SELECT语句精确查询特定列?星号(*)通配符的使用场景与风险有哪些?

    明确指定select语句中的列名能提升查询效率,减少数据传输。1.避免使用select *,列出必要列以增强可读性和安全性;2.结合where和join优化查询逻辑,减少全表扫描;3.合理创建索引以加速检索但需权衡写入性能;4.使用explain分析执行计划定位性能瓶颈;5.用coalesce处理n…

    2026年10月6日 • 用户投稿
    100
  • MySQL和PostgreSQL:哪个更适合您的数据库需求?

    mysql和postgresql:哪个更适合您的数据库需求? 概述:在开发和管理应用程序时,选择合适的数据库管理系统对于数据存储和访问非常重要。本文将介绍两个常见的关系型数据库管理系统:MySQL和PostgreSQL,并探讨它们在不同场景下的适用性。通过对比它们的特点和功能,您可以更好地了解哪个数…

    2026年10月6日
    1500
  • MySQL和TiDB的分布式事务处理能力对比

    mysql和tidb的分布式事务处理能力对比 随着互联网业务规模和复杂度的增加,分布式数据库成为企业选取的首选。MySQL作为一个成熟的关系型数据库,一直以来都具备着良好的性能和可靠性。而TiDB则是新兴的分布式数据库,由PingCAP公司研发,基于Google Spanner的设计理念,迅速崭露头…

    2026年10月6日
    400
  • MySQL vs MongoDB:谁更适合在内存中存储数据?

    mysql vs mongodb:谁更适合在内存中存储数据? 随着大数据和实时应用的快速发展,大量的数据需要高效地存储和检索,并要求具备较低的延迟和高并发处理能力。在这个背景下,数据库管理系统 (DBMS) 的选择变得至关重要。MySQL 和 MongoDB 是两个备受关注的数据库解决方案。本文将重…

    2026年10月6日
    100
  • 数据库安全性:MySQL vs. PostgreSQL

    数据库安全性:mysql vs. postgresql 引言:在当今信息化时代,数据库的安全性问题备受关注。数据库是组织和存储大量敏感信息的地方,因此选择一个安全可靠的数据库管理系统(DBMS)尤为重要。本文将重点比较两个流行的开源DBMS:MySQL和PostgreSQL的安全性,并通过代码示例来…

    2026年10月6日
    100
  • TiDB vs. MySQL:哪个数据库更适合容器化部署?

    tidb vs. mysql:哪个数据库更适合容器化部署? 引言:随着容器化技术的不断发展和普及,越来越多的企业开始将应用程序部署到容器中。在容器化部署环境中,选择适合的数据库系统对于应用程序的可靠性和性能至关重要。本文将比较两个常见的数据库系统:TiDB和MySQL,并探讨它们在容器化部署环境中的…

    2026年10月6日
    1000
  • 如何使用MySQL中的NOW函数获取当前日期和时间

    如何使用mysql中的now函数获取当前日期和时间 MySQL是一种常用的关系型数据库管理系统,它提供了多种函数来处理日期和时间。其中,NOW函数可以用来获取当前日期和时间的值。本文将介绍如何使用MySQL的NOW函数来获取当前日期和时间,并提供相应的代码示例。 使用NOW函数获取当前日期和时间非常…

    2026年10月6日
    100
  • 对比不同城市PHP+MySQL培训后的就业机会

    php+mysql开发者在不同城市的就业机会差异很大。1.北京和上海需求高,薪资高但竞争激烈。2.深圳和广州机会丰富,深圳薪资略高。3.成都和杭州发展迅速,生活成本较低。4.二线城市如武汉、西安、南京机会增加,竞争较小。 在选择PHP+MySQL培训后,很多人都会关心不同城市的就业机会。让我们深入探…

    2026年10月6日
    100
  • 如何使用MySQL中的CONCAT函数将多个字符串合并在一起

    如何使用mysql中的concat函数将多个字符串合并在一起 在MySQL数据库中,有时我们希望将多个字符串合并在一起形成一个新的字符串。MySQL提供了一个非常便捷的函数CONCAT来实现这个功能。本文将向大家介绍如何使用CONCAT函数将多个字符串合并在一起。 首先,我们需要了解CONCAT函数…

    2026年10月6日
    100
  • 大规模数据存储与处理:MySQL和TiDB的对比

    大规模数据存储与处理:mysql和tidb的对比 引言:随着大数据时代的到来,数据存储和处理成为了企业发展中不可或缺的一部分。在数据存储领域,MySQL一直以来都是最受欢迎的关系型数据库之一。然而,随着互联网业务和数据量的爆炸式增长,MySQL逐渐显露出扩展性不足的问题。而TiDB则是一种全新的分布…

    2026年10月6日
    200
  • win10更新1909失败修复方法

    win10更新1909失败修复方法win10更新1909失败修复方法win10更新1909失败修复方法win10更新1909失败修复方法

    今天,小编要跟大家分享一下win10更新1909失败时的修复方法。近期有不少朋友遇到了win10更新1909失败的情况,却不知道该如何处理。希望这篇内容能帮到有需要的朋友们。 第一步,先按下win键和r键组合,打开运行窗口,在里面输入“services.msc”,然后点击确定。 第二步,进入界面后,…

    2026年10月6日 • 用户投稿
    300
  • Hibernate原生查询结果的数据类型识别与Java类型映射

    本文旨在指导开发者如何在Hibernate执行动态原生SQL查询后,有效识别结果集中各列的Java数据类型。我们将探讨em.createNativeQuery()的返回结构,并详细介绍如何通过instanceof运算符进行类型判断,同时提供示例代码和处理不同数据类型时的注意事项,以确保数据处理的准确…

    2026年10月6日
    100
  • MySQL和Oracle:对于并行查询和并行计算的支持对比

    mysql和oracle:对于并行查询和并行计算的支持对比 摘要:本文将重点讨论两个最常用的关系型数据库系统——MySQL和Oracle在并行查询和并行计算方面的支持程度。通过对比它们的特点、架构以及代码示例,旨在帮助读者更好地了解并行查询和并行计算的概念以及两个数据库系统在该领域的不同表现。 关键…

    2026年10月6日
    200
  • MySQL与MongoDB:选择最佳数据库类型的基准测试

    标题:mysql与mongodb:选择最佳数据库类型的基准测试 引言:在现代软件开发中,选择适合自己项目需求的数据库类型是至关重要的。MySQL和MongoDB是两种最为常见的数据库类型,本文将通过进行一系列基准测试来比较它们的性能和适用场景。 简介MySQL是一种关系型数据库管理系统,广泛应用于各…

    2026年10月6日
    100
  • Spring Boot数据库初始化平台属性变更指南

    本文旨在解决Spring Boot应用中平台特定SQL脚本(如schema-mysql.sql)无法执行的问题。核心原因是Spring Boot 2.5版本起,用于指定数据库初始化平台属性已从spring.datasource.platform变更为spring.sql.init.platform。…

    2026年10月6日
    200

发表回复

登录后才能评论
关注微信