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

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

简言:一般来说,事务是必须满足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称呼

在这里来模拟一个转账的操作:AB100元

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)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月6日 08:45:36
下一篇 2025年11月6日 08:46:07

相关推荐

  • 在macOS虚拟环境中安装mysqlclient的全面指南

    本文旨在解决在macos系统python虚拟环境中安装mysqlclient时常见的构建错误,特别是与pkg-config相关的依赖问题。我们将详细介绍如何利用homebrew安装必要的mysql客户端库和pkg-config工具,并通过配置环境变量确保mysqlclient能够成功编译和安装,从而…

    2025年12月15日
    000
  • macOS环境下Python虚拟环境中安装mysqlclient的综合指南

    本教程旨在解决在macos系统python虚拟环境中安装`mysqlclient`时常见的`subprocess-exited-with-error`和`pkg-config`相关错误。文章将详细指导如何利用homebrew安装必要的系统依赖,包括`mysql-client`和`pkg-config…

    2025年12月15日
    000
  • macOS环境下Python虚拟环境安装mysqlclient的完整指南

    本教程详细介绍了在macos系统python虚拟环境中安装`mysqlclient`时,解决`pkg-config`相关编译错误的方法。文章提供了两种主要方案:安装完整的mysql服务器或仅安装mysql客户端库,并强调了正确配置`pkg_config_path`环境变量的重要性,旨在帮助开发者顺利…

    2025年12月14日
    000
  • DynamoDB 实现自增 ID 的两种方法

    本文介绍了在 DynamoDB 中实现自增 ID 的两种常用方法,由于 DynamoDB 本身不支持像 MySQL 那样的原生自增功能,因此需要通过原子计数器或利用排序键的特性来实现。文章详细讲解了每种方法的实现原理、代码示例、优缺点以及适用场景,帮助开发者选择最适合自身业务需求方案。 在关系型数据…

    2025年12月14日
    000
  • 解决Python Tkinter CRUD应用中的MySQL连接不可用错误

    本文旨在解决python tkinter crud应用中常见的`operationalerror: mysql connection not available`错误。我们将深入分析错误堆栈,指导读者诊断并验证mysql数据库连接状态,审查关键的数据库操作函数,并提供健壮的错误处理实践,确保数据插入…

    2025年12月14日
    000
  • SQLAlchemy 声明式模型中指定数据库表模式(Schema)的方法

    本文详细介绍了如何在使用 sqlalchemy 声明式 api 定义和创建数据库表时,指定表所属的数据库模式(schema)。通过在声明式模型类中利用 `__table_args__` 属性并设置 `schema` 参数,开发者可以精确控制表在数据库中的位置,从而避免默认的“public”模式,尤其…

    2025年12月14日
    000
  • python中SQLAlchemy是什么?

    ORM是对象关系映射,将数据库表映射为Python类,行转为对象,字段转属性。SQLAlchemy通过Engine连接数据库,Session操作数据,Base定义模型。例如创建User类对应users表,用session.add()插入数据,无需手写SQL。支持多数据库,提升开发效率与维护性,常用于…

    2025年12月14日
    000
  • Python 异常处理在数据库操作中的应用

    答案:Python数据库操作需通过try-except捕获ConnectionError、OperationalError等异常,结合finally或with语句确保连接关闭与事务回滚,提升程序健壮性。 在使用 Python 进行数据库操作时,异常处理是保障程序稳定运行的关键环节。数据库连接可能因网…

    2025年12月14日
    000
  • python单例模式的应用场景

    单例模式确保类唯一实例并提供全局访问,适用于配置管理、日志记录、数据库连接池和缓存服务,避免资源浪费与数据不一致,提升性能与可维护性。 单例模式确保一个类只有一个实例,并提供全局访问点。在Python中,这种模式常用于需要统一管理和控制资源的场景。 1. 配置管理 应用中通常有一个配置文件(如con…

    2025年12月14日
    000
  • SQLAlchemy声明式风格下如何指定数据库表模式

    本文详细阐述了如何在sqlalchemy的声明式风格中,为数据库表指定特定的schema。通过利用模型类中的`__table_args__`属性,开发者可以设置`schema`参数,从而控制表在postgresql等支持schema的数据库中的命名空间归属。这使得表能够被创建到指定的schema而非…

    2025年12月14日
    000
  • 如何搭建 Python 与 MySQL 的运行环境

    首先安装并配置MySQL,设置root密码并创建数据库;然后安装Python及最新pip;接着安装PyMySQL或mysql-connector-python驱动;最后编写Python脚本测试连接,成功输出数据库版本即表示环境搭建完成。 搭建 Python 与 MySQL 的运行环境 要让 Pyth…

    2025年12月14日
    000
  • Python 项目环境配置的最佳文档写法

    明确Python版本、依赖管理工具及系统要求;2. 按步骤列出克隆、虚拟环境、依赖安装与配置流程;3. 分开发、测试、生产环境说明依赖差异;4. 提供验证命令与常见问题解决方案,确保可操作性。 Python 项目环境配置的最佳文档写法 一个清晰、实用的 Python 项目环境配置文档,能极大降低新成…

    2025年12月14日
    000
  • SQLAlchemy声明式模型中指定数据库表Schema的方法

    本文详细介绍了如何在sqlalchemy的声明式模型中为数据库表指定schema。通过在模型类中利用`__table_args__`属性,开发者可以轻松地将表关联到特定的数据库schema,从而更好地组织和管理数据库结构,尤其适用于支持schema的数据库如postgresql,并提供了完整的代码示…

    2025年12月14日
    000
  • 解决 Windows 7 上 rtmidi Python 库安装失败的问题

    本文旨在帮助解决在 Windows 7 系统上使用 Python 3.8 安装 rtmidi 库时遇到的 “Microsoft Visual C++ 14.0 or greater is required” 错误。文章将分析错误原因,并提供升级 Python 版本至 3.11…

    2025年12月14日
    000
  • 使用SQLAlchemy声明式ORM指定数据库表Schema的教程

    本文详细介绍了如何在sqlalchemy声明式orm中为数据库表指定特定的schema,而非使用数据库的默认schema。通过利用模型类中的`__table_args__`属性,并设置`schema`参数,开发者可以灵活地控制表在不同命名空间中的创建位置。文章将提供具体的代码示例和使用指南,并探讨此…

    2025年12月14日
    000
  • 数据库中检查重复项并报告是否创建了新记录

    本文旨在提供一种使用单个SQL查询在数据库中检查重复记录并报告新记录是否创建的方法。通过在`name`列上创建唯一索引,并结合`ON CONFLICT DO NOTHING`语句,可以有效地避免重复插入,并根据操作结果返回相应的信息。本文将详细介绍实现步骤,并提供示例代码。 在数据库操作中,经常需要…

    2025年12月14日
    000
  • Python3MySQL怎么操作_Python3操作MySQL数据库方法与实例说明

    首先安装PyMySQL驱动并验证导入,然后使用正确参数建立数据库连接,通过游标执行查询或增删改操作,注意提交事务,并在finally块中关闭游标和连接以释放资源。 如果您尝试使用Python3与MySQL数据库进行交互,但无法成功连接或执行查询,可能是由于缺少必要的驱动程序或语法错误。以下是解决此问…

    2025年12月14日
    000
  • python中PyMySQL有什么用

    PyMySQL是Python操作MySQL的轻量库,支持连接数据库、执行SQL、参数化查询防注入、事务管理,并需手动关闭游标和连接。 PyMySQL 是 Python 中用于连接和操作 MySQL 数据库的一个纯 Python 实现的客户端库。它的主要作用是让 Python 程序能够与 MySQL …

    2025年12月14日
    000
  • 在DynamoDB中实现高效自增ID的两种策略

    本文深入探讨了在Amazon DynamoDB中实现类似关系型数据库自增ID的两种高效策略。首先,我们将介绍如何利用原子计数器来生成全局唯一的序列号,并通过两步操作确保数据一致性与无竞争条件。其次,文章将详细阐述如何通过巧妙设计排序键(Sort Key)在项目集合内实现局部序列自增,并结合条件写入机…

    2025年12月14日
    000
  • Mypy类型检查一致性:解决本地与CI环境差异的教程

    本文旨在解决Mypy在本地开发环境(特别是与pre-commit结合时)与CI/CD管道(如GitHub Actions)中行为不一致的问题。我们将深入探讨pre-commit与直接Mypy命令执行机制的差异,分析导致CI失败而本地通过的潜在原因,包括环境配置、依赖版本和Mypy配置文件的差异。教程…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信