为什么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. 参考文档

为什么NoSQL不支持事务的更多相关文章

  1. Elasticsearch不支持事务有什么好的弥补方案

    1.问题 源自星球同学的提问:es如何与hive或mysql结合使用?es不支持事务有什么好的弥补方案吗? 2.事务的核心概念 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下ACID四个 ...

  2. MySql不支持事务解决

    用的是一个绿色版的mysql数据库,发现不支持事务,在网络上搜集资料找到解决方案: 1.执行语句  SHOW ENGINES; 如果发现InnoDB全部显示为“YES”,说明该版本的数据库支持事务 2 ...

  3. 遇过的坑(2)—MyISAM表类型不支持事务操作

    最近需要通过JDBC对数据库做事务型操作,实践时发现,并没有达到想要的效果,表现在:1.每次执行executeUpdate()后,数据就马上能在DB中查到.但按理来说,我还没执行commit(),DB ...

  4. 第三章(附)mysql表类型MyISAM和InnoDB区别(决定了是否支持事务)

    mysql表类型MyISAM和InnoDB区别 MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问 ...

  5. Spring+Mybatis多数据源的一种实现方式,支持事务

    最近一个项目用到了多个数据库,所以需要实现动态切换数据源来查询数据,http://www.cnblogs.com/lzrabbit/p/3750803.html这篇文章让我受益匪浅,提供了一种自动切换 ...

  6. MongoDB与Spring整合(支持事务)——SpringDataMongoDB

    1.将MongoDB设置为复制集模式 a.修改 mongod.cfg 文件,添加replSetName复制集名称 #replication: replication: replSetName: &qu ...

  7. 这么小的key-val数据库居然也支持事务——与短跑名将同名的数据库Bolt

    传送门: 柏链项目学院 什么是Bolt?   Bolt是一个纯净的基于go语言编写的key-val数据库,该项目受到LMDB项目的启发,目标是提供一个不需要完整服务器的简单.快速.可靠的数据库.    ...

  8. MySQL(存储过程,支持事务操作)

    day61 保存在MySQL上的一个别名   >   一坨SQL语句 -- delimiter // -- create procedure p1() -- BEGIN -- select * ...

  9. 4、什么是事务?MySQL如何支持事务?

    什么是事务? 事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行.程序和事务是两个不同的概念.一般而言:一段程序中可能包含多个事务.(说白了就是几步的数据库操作 ...

  10. 什么是事务?MySQL如何支持事务?

    什么是事务? 事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行.程序和事务是两个不同的概念.一般而言:一段程序中可能包含多个事务.(说白了就是几步的数据库操作 ...

随机推荐

  1. Django4全栈进阶之路11 view视图

    在 Django 4 中,视图(View)是一个处理请求并返回响应的 Python 函数或类的组合.视图函数通常是处理请求的主要逻辑,因此它是 Django Web 应用程序的重要组成部分. 视图函数 ...

  2. MMCM and PLL Dynamic Reconfiguration

    Reconfiguration is performed through the DRP. The DRP provides access to the configuration bits that ...

  3. phpstudy-sqlilabs-less-3

    题目:GET - Error based - Single quotes with twist 基于错误的单引号GET型变形注入 ?id=1 )and 1=2--+ ?id=1 "and 1 ...

  4. AcWing 3956. 截断数组

    给定一个长度为 n 的数组 a1,a2,-,an. 现在,要将该数组从中间截断,得到三个非空子数组. 要求,三个子数组内各元素之和都相等. 请问,共有多少种不同的截断方法? 输入格式 第一行包含整数 ...

  5. 如何使用Map处理Dom节点

    本文浅析一下为什么Map(和WeakMap)在处理大量DOM节点时特别有用. 我们在JavaScript中使用了很多普通的.古老的对象来存储键/值数据,它们处理的非常出色: const person ...

  6. 手动封装XMLHttpRequest

    自己动手封装一个XMLHttpRequest, 兼容低版本浏览器,自动检测post与get 类型请求,自动参数拼接,参数类型辨别 <!DOCTYPE html> <html> ...

  7. Python基础 - python解释器

    Python解释器是什么 Python解释器本身也是个程序, 它是解释执行 Python代码的,所以叫解释器. 没有它,我们的Python代码是没有办法运行的. 怎么下载安装Python解释器   官 ...

  8. Hugging News #0526: Hugging Cast 发布第一期、邀请来认领自己的论文啦!

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  9. ensp 链路聚合

    链路聚合(Link Aggregation)   指将多个物理端口汇聚在一起,形成一个逻辑端口,以实现出/入流量吞吐量在各成员端口的负荷分担,链路聚合在增加链路带宽.实现链路传输弹性和工程冗余等方面是 ...

  10. Python正则表达式完全指南

    本篇文章将深入探讨python的一项强大工具:正则表达式.正则表达式是一个强大的文本处理工具,可以用来匹配,搜索,替换和解析文本.我们将逐步展示如何在Python中使用正则表达式,包括其基本语法,常见 ...