MySQL事务理解

本文参考自《高性能MySQL》
知道数据库的人都应该清楚,事务是数据库高级特性的基础,如果你不了解事务的话,那基本可以确定你并不会数据库,好了,废话不多说了,直接切入主题吧!

一、什么是事务

首先,什么是事务呢?
在数据库里,事务就是一组原子性的SQL查询,或者说一个独立的工作单元。简而言之就是一组执行特定功能的SQL语句,这些语句要么都执行成功,要么都执行失败,不能可能部分成功或者部分失败。这样一个过程就称做事务。

二、事务的特性

既然谈到事务,那就不可能避免地要谈及事务的特性;事务具有ACID的特性,那么是什么呢?
A即原子性(atomicity)、C即一致性(consistency)、I即隔离性(isolation)、D即持久性(durability)。接下来将分别介绍。

2.1 原子性

原子性:顾名思义就是像原子一样不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。
注意::这部分和事务的概念有点相似,但是不要混肴,事务是一系列执行语句的组合,这一组合执行的整个过程统称为一个事务,而原子性是事务的原子性,并不是执行语句的原子性,执行语句本身可以执行失败的,但是一旦引入事务的概念,那么就要求其内部的语句必须配合原子性。

2.2 一致性

一致性:数据库总是从一个一致性状态转换到另外一个一致性状态的(从一个正常状态转换为另一个正常状态)。
什么意思呢?
就是当我们事务内部的SQL语句执行后,事务提交后的状态与提交前的状态必须要在符合逻辑、符合业务需求,不会产生增量或者缺量的问题
举个例子:如果你左口袋十五块钱,右口袋五块钱,总共二十块钱,现在你要从左口袋拿出3块钱放到右口袋中(拿出钱,放入钱这整个过程就是一个事务);这个过程我们可以拆分为如下两个步骤:

  1. 从左边口袋拿出三块钱;
  2. 将拿出的三块钱放入右边口袋;

现在我们考虑一种情况,如果你完成了第一步,然后在进行第二步操作的时候,出现问题,没办法放右边口袋了(不考虑放回左口袋),此时,你左右口袋的钱总和为17,莫名其妙少了3块钱,这时事务就会结束,那与你拿钱前的状态(总和20)不一致,事务的一致性就是这样,必须要一直,这种情况下,事务是不会执行成功,会进行回滚(回到拿钱前的20块状态那时)

2.3 隔离性

隔离性:各个事务之间的操作是不可见的(除非设置隔离级别:未提交读 read uncommitted)。
事务的隔离性有分隔离级别,不同的级别,具有不同的作用;主要分为:未提交读(read uncommitted)、提交读(read committed)、可重复读(repeatable read)、可串行化(serializable)

2.3.1 read uncommitted

在read uncommitted级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取到未提交的数据,这也被成为脏读。简单理解就是就是在不同的事务下,当前事务可以读到另外事务未提交的数据,简单来说就是可以读到脏数据。
脏读举例:事务A在执行的过程修改了数据库中的数据,这时事务B插了进来,读取到了事务A修改之后的数据并且提交了上去,这时事务A由于某些原因进行了回滚,那么事务B读取的就是事务A的脏数据。

2.3.2 read committed

大多数数据库默认的隔离级别都是read committed(MySQL不是)。read committed满足前面提到的隔离性的简单定义:一个事务开始时,只能看见已经提交的事务所有的修改。换句话说,一个事务开始直到提交之前,所做的任何修改对其他事务都是不可见的。有时候这个级别也被称为不可重复读,因为两次执行同样的查询,可能会得到不一样的结果。简单理解就是,提交了其他事务才能读取数据
不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。

2.3.3 repeatable read

repeatable read 解决了脏读的问题,该级别保证了在同一个事务中,多次读取同样记录的结果是一致的,但是无法解决幻读
幻读:事务A 按照一定条件进行数据读取,期间事务B 插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B 新插入的数据称为幻读。
注意:不可重复读和幻读的区别:在同一事务中,不可重复读是select同一个数据发现查询到的结果跟刚才不一样,幻读是比不可重复读高一个级别的错误,读取同一条数据发现跟刚才是一样的,只有读取一堆数据发现忽然多了一个,或者少了一个,总之,不可重复读针对的是同一条数据,幻读针对的是一片数据,MySQL默认隔离级别是可重复读。

2.3.4 serializable

serializable是最高级别的隔离,通过强制事务串行执行,避免了幻读问题。简单来说,serializable会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁竞争问题。
隔离级别表如下:
在这里插入图片描述

2.3.4 扩展

另外,在隔离级别上,MySQL的InnoDB使用的是多版本并发控制(MVCC)来保证多线程并发的数据一致性问题。

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

2.4 持久性

持久性:一旦事务提交,其所做的所有修改就会永久保存到数据库中,即使系统崩溃修改的数据也不会丢失。


笔者在此推荐一篇博客,个人觉得写的不错,另外原本想增加一章节关于数据库存储引擎以及逻辑架构的,但是看到这篇博客有介绍,写的比较好在此推荐大家可以参阅该博客:
博客连接地址https://www.cnblogs.com/kismetv/p/10331633.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值