为什么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. Redis数据结构一之对象的介绍及各版本对应实现

    本文首发于公众号:Hunter后端 原文链接:Redis数据结构一之对象的介绍及各版本对应实现 本篇笔记开始介绍 Redis 数据结构的底层实现. 当我们被问到 Redis 中有什么数据结构,或者说数 ...

  2. vue全家桶进阶之路28:项目仓库Gitee

    Gitee(之前称为GitCafe)是一种基于web的Git仓库托管服务,在中国很受欢迎.它为开发人员提供了一个平台,可以托管他们的Git仓库,与其他开发人员协作,并管理他们的代码. https:// ...

  3. 1451, 'Cannot delete or update a parent row: a foreign key constraint fails

    问题描述:1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`sysProDB4`.`IM003 ...

  4. 【lwip】15-NETCONN接口

    前言 终于到接口层了. 原文:李柱明博客:https://www.cnblogs.com/lizhuming/p/17442931.html ‍ 框架描述 前面我们已经学完了,都知道raw接口了,其实 ...

  5. Java动态数组及数组排序的三种常用方法

    一.动态数组 1.数组的定义: ​ 用于存储相同数据类型的一组连续的存储空间 2.数组的特点: ​ 数组的长度一旦定义,则不可改变 ​ 访问数组的元素需要通过下标(索引)访问,下标从0开始 ​ 数组是 ...

  6. 生信服务器 | Linux 时间戳和标准时间

    在 Linux 系统中,有许多场合都使用时间戳的方式表示时间,即从1970年1月1日起至当前的天数或秒数.如/etc/shadow里的密码更改日期和失效日期,还有代理服务器的访问日志对访问时间的记录等 ...

  7. JS工具函数

    工具函数 用于工程化开发,记录,备用 返回 [min, max) 间的随机整数 /** 返回 [min, max) 间的随机整数 */ export function getRandom(min, m ...

  8. 一篇文章带你入门HBase

    本文已收录至Github,推荐阅读 Java随想录 微信公众号:Java随想录 目录 HBase特性 Hadoop的限制 基本概念 NameSpace Table RowKey Column Time ...

  9. HTTP请求:requests模块基础使用必知必会

    1 背景 http请求是常见的一种网页协议,我们看到的各种网页,其实都是发送了http请求得到了服务器的响应,从而将数据库中复杂的数据以简单.直观的方式呈现出来,方便大众阅读.使用.而如何发送http ...

  10. CF1817E Half-sum

    题意 有一个大小为 \(N\) 的非负整数集合 \(A\),每次你可以从集合中取任意两个数,并将它们的平均数放回序列.不停操作,知道集合最后剩下两个数.请求出这两个数的差的绝对值的最大值对 \(10^ ...