我是平也,这有一个专注Gopher技术成长的开源项目「go home」

背景介绍

想必事务大家都已经非常熟悉了,它是一组SQL组成的一个执行单元,要么全执行要么全不执行,这也是它的一个特性——原子性。而事务的应用场景也非常广泛,最经典的就是转账问题,A给B打钱,不能出现A钱扣了B还没收到的状况,否则业务就乱套了。

事务的特性

于是呢,根据用户对这些场景的严苛要求,总结出了事务应该具备的四个特性,分别是原子性、一致性、隔离性、持久性,简称事务的ACID属性。

原子性

Atomicity,事务是一个最小的执行单位,事务里面的SQL要么全执行,要么全不执行,就拿A与B转账为例,一条语句从A里扣钱,另一条语句往B身上加钱,如果这两条语句不能全部执行,而是成功了一部分,那事务就没有存在的意义了。

隔离性

Isolate,顾名思义就是将事务与另一个事务隔离开,为什么要隔离呢?如果一个事务正在操作的数据被另一个事务修改或删除了,最后的执行结果可能无法达到预期。如果没有隔离性还会导致其他问题,稍后会有所说明。

持久性

Durable,意为事务完成了对数据的修改之后,修改的结果是永久性生效的。

一致性

Consistent,把一致性放在最后讲的原因是前三个比较容易理解,而一致性的概念很模糊。

一致性是指事务使得应用系统从一个正确的状态到另一个正确的状态。

知乎上面一个高赞回答的很特别,原子性、隔离性、持久性是数据库事务的基本特征,而一致性是由AID这三个特征来保证的。

那么怎么理解这句话呢?还拿转账为例,如果A手里有100元,转给B120元,显然A手里的钱不够扣,假如你给金额这一列设置了不能小于0的约束,那么在事务执行的时候监测到约束没被满足,就会回滚,这时可以说事务保证了一致性。同样的,如果你没有添加约束,而是在业务层做了校验,并做了回滚,那么也可以说事务保证了一致性。那如果数据库和业务层都没有做约束呢,A的钱不就变为负数了吗?这实际上也是保证了一致性,因为执行前后并没有破坏任何约束,它的状态一直都是正确的。

事务并发带来的问题

前面讲到了事务的隔离性,如果要提升系统的吞吐量,当有多个任务需要处理时,应当让多个事务同时执行,这就是事务的并发。既然事务存在并发执行,那必然产生同一个数据操作时的冲突问题,来看一下都会出现什么问题。

更新丢失

Lost Update,当两个事务更新同一行数据时,双方都不知道对方的存在,就有可能覆盖对方的修改。比如两个人同时编辑一个文档,最后一个改完的人总会覆盖掉前面那个人的改动。

脏读

Dirty Reads,一个事务在执行时修改了某条数据,另一个事务正好也读取了这条数据,并基于这条数据做了其他操作,因为前一个事务还没提交,如果基于修改后的数据进一步处理,就会产生无法挽回的损失。

不可重复读

Non-Repeatable Reads,同样是两个事务在操作同一数据,如果在事务开始时读了某数据,这时候另一个事务修改了这条数据,等事务再去读这条数据的时候发现已经变了,这就是没办法重复读一条数据。

幻读

Phantom Read,与上方场景相同,事务一开始按某个查询条件没查出任何数据,结果因为另一个事务的影响,再去查时却查到了数据,这种就像产生幻觉了一样,被称作幻读。

事务的四种隔离级别

首先,更新丢失这种问题应该是由应用层来解决的,因为数据库没有办法控制用户不去更新某条数据。但是另外三个问题是可以得到解决的,既然有方案解决解决它不就好了,干嘛还要设置这么多隔离级别呢?

刚才说了,如果我们要性能好、吞吐量提升,那就不得不付出一些代价,如果要做到完全没有副作用,那么就只需要让事务排队执行就好了,一个一个执行绝对不会出现脏读幻读的问题,但是这样会导致数据库处理的非常慢。那怎么办呢?官方唯一能做的就是给你提供各种级别的处理方式,由你根据具体业务场景选择,于是就有了隔离级别。

读未提交 Read uncommitted

读未提交其实就是事务没提交就可以读,很显然这种隔离级别会导致读到别的还没提交的数据,一旦基于读到的数据做了进一步处理,而另一个事务最终回滚了操作,那么数据就会错乱,而且很难追踪。总的来说说,读未提交级别会导致脏读。

读提交 Read committed

顾名思义就是事务提交后才能读,假设你拿着银行卡去消费,付钱之前你看到卡里有2000元,这个时候你老婆在淘宝购物,赶在你前面完成了支付,这个时候你再支付的时候就提示余额不足,但是分明你看到卡里的钱是够的啊。

这就是两个事务在执行时,事务A一开始读取了卡里有2000元,这个时候事务B把卡里的钱花完了,事务A最终再确认余额的时候发现卡里已经没有钱了。很显然,读提交能解决脏读问题,但是解决不了不可重复读。

Sql Server,Oracle的默认隔离级别是Read committed。

可重复读 Repeatable read

看名字就看出来了,它的出现就是为了解决不可重复读问题,事务A一旦开始执行,无论事务B怎么改数据,事务A永远读到的就是它刚开始读的值。那么问题就来了,假设事务B把id为1的数据改成了2,事务A并不知道id发生了变化,当事务A新增数据的时候却发现为2的id已经存在了,这就是幻读。

MySQL的默认隔离级别就是Repeatable read。

串行化 serializable

这个就是最无敌的存在了,所有的事务串起来一个个执行,因为没有并发的场景出现了,什么幻读、脏读、不可重复读统统都不存在的。但是同样的,基本并发能力会非常差。最终,到底什么隔离级别完全要根据自己的业务场景选择,没有最好的,只有最适合的。

表格比较

隔离级别 脏读 不可重复读 幻读
Read uncommitted
Read committed
Repeatable read
serializable

感谢大家的观看,如果觉得文章对你有所帮助,欢迎关注公众号「平也」,聚焦Go语言与技术原理。

MySQL的事务隔离级别是什么?的更多相关文章

  1. MySQL数据库详解(三)MySQL的事务隔离剖析

    提到事务,你肯定不陌生,和数据库打交道的时候,我们总是会用到事务.最经典的例子就是转账,你要给朋友小王转 100 块钱,而此时你的银行卡只有 100 块钱. 转账过程具体到程序里会有一系列的操作,比如 ...

  2. 事务的隔离级别,mysql默认的隔离级别是什么?

    读未提交(Read uncommitted),一个事务可以读取另一个未提交事务的数据,最低级别,任何情况都无法保证. (1)所有事务都可以看到其他未提交事务的执行结果 (2)本隔离级别很少用于实际应用 ...

  3. mysql基础 事务的认识和使用

    事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务是恢复和并发控制的基本单位. 在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序 ...

  4. 数据库事务隔离级ORACLE数据库事务隔离级别介绍

    本文系转载,原文地址:http://singo107.iteye.com/blog/1175084 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committ ...

  5. MySQL之事务隔离级别--转载

    转自:http://793404905.blog.51cto.com/6179428/1615550 本文通过实例展示MySQL事务的四种隔离级别. 1 概念阐述 1)Read Uncommitted ...

  6. MySQL数据库事务隔离级别(Transaction Isolation Level)

    转自: http://www.cnblogs.com/zemliu/archive/2012/06/17/2552301.html  数据库隔离级别有四种,应用<高性能mysql>一书中的 ...

  7. mysql数据库事务详细剖析

    在写之前交代一下背景吧! 做开发也好久了,没怎么整理过知识,现在剖析一下自己对数据库事务的认识,以前用sqlserver,现在转java后又用mysql.oracle.我这块就主要解释一下mysql数 ...

  8. Mysql数据库事务隔离级别

    事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列.事务ACID属性,即原子性(Atomicity).一致性(Consistency ...

  9. MySQL数据库事务及其特性

    一.事务概念 事务就是一个程序执行单元,里面的操作要么都做,要么都不做. 二.事务特性 事务有四个非常重要的特性(ACID): 原子性(Atomicity):事务是不可分割的整体,所有操作要么全做,要 ...

随机推荐

  1. c# 对SOAP返回XML字符串的解析方法

    <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP:Head ...

  2. Flutter 实现不同样式(有样式) 的TextField (可自定义),类似微博#话题#、@用户,(给TextField加TextSpan)

    描述 先上效果图 在项目中,有 @ 和 话题功能,需要在编辑时即可回显,但是官方原生的TextField不支持对部分文字定义不同的样式,所以封装了一个. 注意:这不是富文本插件,不支持在输入框中显示图 ...

  3. Elasticsearch系列---使用中文分词器

    前言 前面的案例使用standard.english分词器,是英文原生的分词器,对中文分词支持不太好.中文作为全球最优美.最复杂的语言,目前中文分词器较多,ik-analyzer.结巴中文分词.THU ...

  4. Redis缓存设计与性能优化

    Redis我们一般是用作缓存,扛并发:或者用于某些特定的业务场景,比如前面说到redis各种数据类型的使用场景以及redis的哨兵和集群模式. 这里主要整理了下redis用作缓存,存在的一些问题,以及 ...

  5. Hive知识点

    1.Hive是一种建立在Hadoop文件系统上的数据仓库架构,并对存储在HDFS中的数据进行分析和管理:(也就是说对存储在HDFS中的数据进行分析和管理,我们不想使用手工,我们建立一个工具把,那么这个 ...

  6. 2020年PHP 面试问题(二)

    一.什么是 CGI?什么是 FastCGI?php-fpm,FastCGI,Nginx 之间是什么关系? CGI,通用网关接口,用于WEB服务器和应用程序间的交互,定义输入输出规范,用户的请求通过WE ...

  7. 数据科学中需要知道的5个关于奇异值分解(SVD)的应用

    介绍 "Another day has passed, and I still haven't used y = mx + b." 这听起来是不是很熟悉?我经常听到我大学的熟人抱怨 ...

  8. 关于TensorFlow九件你非知不可的事

    来源 | Hackernoon 译者 | Revolver 前些天我参加了7 月24 日在美国旧金山举行的Google Cloud Next 2018 大会,其中的一个演讲( What's New w ...

  9. Arcgis中制作热力图

    摘要 使用核函数根据点或折线 (polyline) 要素计算每单位面积的量值以将各个点或折线 (polyline) 拟合为光滑锥状表面. 插图

  10. Python第十二章-多进程和多线程01-多进程

    多进程和多线程 一.进程 1.1 进程的引入 现实生活中,有很多的场景中的事情是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的:试想,如果把唱歌和跳舞这2件事情分开依次 ...