为什么NoSQL不支持事务
为什么NoSQL不支持事务
1. 背景
看书《Neo4j权威指南》的时候,发现个问题:日常的NoSQL都不支持事务(ACID)。
2. 问题
事务对数据的存储过程是有利的,既然事情是有利的,理论上存储型数据库都应该支持事务。但事实上是只有很少的一部分数据库支持事务,比如 MySQL,Neo4j,并且MySQL也只有部分存储引擎才支持事务,比如InnoDB。
那么为什么一般NoSQL都没有实现事务呢? 比如常用的几个:Redis,MangoDB,HBase,ES 等。
一起在网上查查,看有没有相关的文档介绍。
3. 什么是事务(ACID)
先复习下什么是事务(ACID)呢?
事务是由一系列对系统中数据进行访问或者更新操作组成的一个程序执行逻辑单元(Unit),也就是说,事务是要求这一组程序要么都执行成功,要么都不执行(执行失败)。
ACID,是指 数据库管理系统 ( DBMS )在写入或更新资料的过程中,为保证 事务 (transaction)是正确可靠的,所必须具备的四个特性:
- 原子性 Atomicity :要保证事务中包裹的逻辑,要么全部执行成功,要么全部都不执行。
- 一致性 Consistency:要保证事务在执行前后,数据库都要处于正确状态,满足完整性约束。
- 隔离性 Isolation:多个事务并发执行的时候,一个事务不应该影响另一个事务,保证所有事务都好像在独立运行。
- 持久性 Durability:事务处理完成,对数据的修改是永久性的,即使系统故障,都不会丢失。
我到现在也没有理解,为什么是ACID,而不是AID或者C。在我的理解中,AID是为了保证C存在的,而且只要保证了AID,就能得到C的结果,所以我认为C和AID并不是一个层次上的概念。接下来的解释,都是基于我这种理解范畴的。
下面的话参考引用了知乎上的一篇文章,跟我的理解是一样的,文章链接
ACID里的AID都是数据库的特征,也就是依赖数据库的具体实现.而唯独这个C,实际上它依赖于应用层,也就是依赖于开发者.这里的一致性是指系统从一个正确的状态,迁移到另一个正确的状态.什么叫正确的状态呢?就是当前的状态满足预定的约束就叫做正确的状态.而事务具备ACID里C的特性是说通过事务的AID来保证我们的一致性.
做个比喻事务就好比一个保镖,我们提到事务就会说ACID,而我们提到保镖会说强壮,保护安全,好功夫,踏实.这里强壮,好功夫和踏实都是保镖自己的特征,而安全是属于你的,而你通过保镖的特征来保护你的安全.
这里我们举个大家都在说的财务系统的例子.
A要向B支付100元,而A的账户中只有90元,并且我们给定账户余额这一列的约束是,不能小于0.那么很明显这条事务执行会失败,因为90-100=-10,小于我们给定的约束了.
这个例子里,支付之前我们数据库里的数据都是符合约束的,但是如果事务执行成功了,我们的数据库数据就破坏约束了,因此事务不能成功,这里我们说事务提供了一致性的保证.然后我们再看个例子
当然,也可以把C解释成与AID一致的层面,比如:数据一致性就是数据要满足一定约束条件,如果事务的执行违反了这个约束条件,那么事务应该失败,这样理解的话,就是ACID是一个层面的特性了。
不管是“AID 是特性,C是目的”,还是“ACID 都是 特性”,都看个人理解,然而这种个人理解无论是哪种,都是有利于“事务”的制定和发展的。
至于ACID怎么实现,这里不做赘述。
4. 关系型数据库和非关系型数据库
NoSQL又叫非关系型数据库,再回一下关系型数据库和非关系型数据库对的区别是什么。
关系数据库管理系统(RDBMS)能够非常有效地管理事务数据。关系数据库拥有原子性、一致性、隔离性和持久性(ACID)属性,这些属性使关系数据库成为企业管理数据的主要产品,并使它们跨越各种关键的业务功能。例子包括企业资源规划(ERP)、客户关系管理(CRM)、数据仓库和许多类似的应用程序。
NoSQL数据库不具备关系型数据库的全部特性,但是它能提供一个快速检索信息的机制。NoSQL数据库是高度分布的数据库,它能在普通商用硬件上运行,并只提供很少事务支持或没有事务支持;NoSQL支持非常灵活的模式定义(甚至不存在模式定义),因此它们非常适合快速存储、检索和更新非结构化的数据
5. 为什么NoSQL不支持事务(ACID)
NoSQL面对的场景与RDBMS并不相同,NoSQL主要应用场景在于 大数据量,高并发等场景,即 集群化,分布式是必然的架构。而这也是NoSQL不支持事务的本质原因。
因为分布式情况下:一系列写操作中访问的数据可能位于不同的分区服务器,这样的事务就变成分布式事务,在分布式事务中实现原子性需要彼此协调,而协调是耗费时间的,每台机器在一个大事务过程中必须依次确认,这就需要一种协议确保一个事务中没有任何一台机器写操作失败,这种协调是昂贵的,会增加延迟时间,关键问题是,当协调没有完成时,其他操作是不能读取事务中写操作结果的,针对分布式事务的分布式协调对整体数据库性能有严重影响,不只是吞吐量还包括延迟时间,这样大部分NoSQL数据库因为性能问题就选择不提供分布式事务。
换句话说,ACID就是关系型数据库的规则,不能套用到非关系型数据库上。
6. MySQL 是否支持分布式
广义上讲,MySQL是支持分布式的,分布式CAP理论下,它实现了CA。狭义上讲,MySQL是不支持分布式的,因为分布式理论中,P是必不可少的,也就是说,只有AP和CP可选,而属于CA的MySQL并不能说是支持分布式。同时,也有人说,正是因为MySQL是CA系统,所以MySQL可以支持ACID。也正是因为NoSQL大都是CP系统者是AP系统,所以NoSQL没办法支持ACID。
说明:虽然MySQL有集群化部署,但写操作的水平扩展只能依靠sharding(分库分表),但再怎么分,对数据的写永远是单机的(即一条数据只会写在一个服务器上)。

X. 参考文档
- http://www.codebaoku.com/it-mysql/it-mysql-193184.html
- https://www.cnblogs.com/cciejh/p/acid.html
- https://blog.51cto.com/u_15064656/4743241
- https://www.zhihu.com/question/30272728/answer/72476703
- https://jishuin.proginn.com/p/763bfbd5d83c
- https://cloud.tencent.com/developer/article/1630745
为什么NoSQL不支持事务的更多相关文章
- Elasticsearch不支持事务有什么好的弥补方案
1.问题 源自星球同学的提问:es如何与hive或mysql结合使用?es不支持事务有什么好的弥补方案吗? 2.事务的核心概念 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下ACID四个 ...
- MySql不支持事务解决
用的是一个绿色版的mysql数据库,发现不支持事务,在网络上搜集资料找到解决方案: 1.执行语句 SHOW ENGINES; 如果发现InnoDB全部显示为“YES”,说明该版本的数据库支持事务 2 ...
- 遇过的坑(2)—MyISAM表类型不支持事务操作
最近需要通过JDBC对数据库做事务型操作,实践时发现,并没有达到想要的效果,表现在:1.每次执行executeUpdate()后,数据就马上能在DB中查到.但按理来说,我还没执行commit(),DB ...
- 第三章(附)mysql表类型MyISAM和InnoDB区别(决定了是否支持事务)
mysql表类型MyISAM和InnoDB区别 MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问 ...
- Spring+Mybatis多数据源的一种实现方式,支持事务
最近一个项目用到了多个数据库,所以需要实现动态切换数据源来查询数据,http://www.cnblogs.com/lzrabbit/p/3750803.html这篇文章让我受益匪浅,提供了一种自动切换 ...
- MongoDB与Spring整合(支持事务)——SpringDataMongoDB
1.将MongoDB设置为复制集模式 a.修改 mongod.cfg 文件,添加replSetName复制集名称 #replication: replication: replSetName: &qu ...
- 这么小的key-val数据库居然也支持事务——与短跑名将同名的数据库Bolt
传送门: 柏链项目学院 什么是Bolt? Bolt是一个纯净的基于go语言编写的key-val数据库,该项目受到LMDB项目的启发,目标是提供一个不需要完整服务器的简单.快速.可靠的数据库. ...
- MySQL(存储过程,支持事务操作)
day61 保存在MySQL上的一个别名 > 一坨SQL语句 -- delimiter // -- create procedure p1() -- BEGIN -- select * ...
- 4、什么是事务?MySQL如何支持事务?
什么是事务? 事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行.程序和事务是两个不同的概念.一般而言:一段程序中可能包含多个事务.(说白了就是几步的数据库操作 ...
- 什么是事务?MySQL如何支持事务?
什么是事务? 事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行.程序和事务是两个不同的概念.一般而言:一段程序中可能包含多个事务.(说白了就是几步的数据库操作 ...
随机推荐
- ES 数据没了?谁动了我的数据?
背景 我们在使用 Elasticsearch 的时候,可能会遇到数据"丢"了的情况.有可能是数据没成功写入 ES 集群,也可能是数据被误删了. 针对数据被误删,有没有好的解决办法呢 ...
- 基于Jmeter+ant+Jenkins+钉钉机器人群通知的接口自动化测试
前言 搭建jmeter+ant+jenkins环境有些前提条件,那就是要先配置好java环境,本地java环境至少是JDK8及以上版本,最好是JAVA11或者JAVA17等较高的java环境,像jen ...
- RWKV – transformer 与 RNN 的强强联合
在 NLP (Natural Language Processing, 自然语言处理) 领域,ChatGPT 和其他的聊天机器人应用引起了极大的关注.每个社区为构建自己的应用,也都在持续地寻求强大.可 ...
- Docker运行Django框架
Django框架 创建django-pg项目目录 [root@docker ~]# mkdir docker-compose-django [root@docker ~]# cd docker-com ...
- 10个 Istio 流量管理 最常用的例子,你知道几个?
10 个 Istio 流量管理 最常用的例子,强烈建议收藏起来,以备不时之需. 为了方便理解,以Istio官方提供的Bookinfo应用示例为例,引出 Istio 流量管理的常用例子. Bookinf ...
- 通用密钥,无需密码,在无密码元年实现Passkeys通用密钥登录(基于Django4.2/Python3.10)
毋庸讳言,密码是极其伟大的发明,但拜病毒和黑客所赐,一旦密码泄露,我们就得绞尽脑汁再想另外一个密码,但记忆力并不是一个靠谱的东西,一旦遗忘密码,也会造成严重的后果,2023年业界巨头Google已经率 ...
- Python Django Web开发实战
Python Django全面介绍 Django是一个非常强大的Python Web开发框架,它以"快速开发"和"干净.实用的设计"为设计宗旨.本文将从Djan ...
- 细节决定成败,聊聊JS的类型(上)
今天我们来讲讲 JavaScript 的内容,在这个部分,我首先想跟你聊一聊类型. JavaScript 类型对每个前端程序员来说,几乎都是最为熟悉的概念了.但是你真的很了解它们吗?我们不妨来看看下面 ...
- JavaScript中this的绑定
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path s ...
- 阿里云容蓓:DCDN 助力云原生时代的应用构建及最佳实践
在数字化转型速度不断提升的今天,大带宽.低时延.高并发的场景不断涌现,内容分发网络(Content Delivery Network,CDN)应用需求还在不断攀升,打造更高质量的CDN服务将成为新时代 ...