MySQL 事务

本文所说的 MySQL 事务都是指在 InnoDB 引擎下,MyISAM 引擎是不支持事务的。

事务具有四大特性:

1、原子性

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

2、一致性

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

3、隔离性

数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

4、持久性

事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

今天要说的就是隔离性


并发下事务会产生的问题

脏读

事务A读取了事务B修改但未提交的数据X,然后事务B回滚了,这样事务A就形成了脏读。

不可重复读

事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了并提交了事务,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。通常针对数据更新操作

幻读

幻读是针对数据插入/删除操作来说的。事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。

不可重复读和幻读比较:
两者有些相似,但是前者针对的是更新/删除,后者针对的插入


事物隔离级别查看及修改

首先说明一下MySQL查看和修改事务隔离级别的几个命令:

1、查看当前会话事务隔离级别

select @@transaction_isolation

2、查看全局事务的隔离级别 

select @@global.transaction_isolation;

3、修改当前会话事务隔离级别

SET session TRANSACTION ISOLATION LEVEL Serializable;

(参数可以为:Read uncommitted|Read committed|Repeatable read|Serializable)

4、修改全局事务隔离级别

SET global TRANSACTION ISOLATION LEVEL Serializable;

(参数可以为:Read uncommitted|Read committed|Repeatable read|Serializable)

注:修改了会话的事务隔离级别,比如MyBatis,getSqlSession()的时候,只针对这一次拿到的Session有效;比如CMD命令行,只对这一次的窗口有效。

修改了全局的事务隔离级别,那么针对此后所有的会话有效,当前已经存在的会话不受影响

MySQL 中执行事务

begin;
select * from xxx;
commit; -- 或者 rollback;

分析这几个隔离级别

接下来我会用一张表来做一下验证,表结构简单如下:

mysql> SELECT * FROM user;
+----+-----------------+------+
| id | name            | age  |
+----+-----------------+------+
|  1 | 古时的风筝        |    1 |
+----+-----------------+------+

读未提交

就是一个事务能够看到其他事务尚未提交的修改,这是最低的隔离水平。

读未提交隔离级别是不加锁的,所以它的性能是最好的,没有加锁、解锁带来的性能开销。但有利就有弊,这基本上就相当于裸奔啊,所以它连脏读的问题都没办法解决。

set global transaction isolation level read uncommitted;

启动两个事务,分别为事务A和事务B

顺着时间轴往表示两事务中操作的执行顺序,重点看图中 age 字段的值。

读未提交,其实就是可以读到其他事务未提交的数据,但没有办法保证你读到的数据最终一定是提交后的数据,如果中间发生回滚,那就会出现脏数据问题,读未提交没办法解决脏数据问题。更别提可重复读和幻读了,想都不要想。

读提交

事务能够看到的数据都是其他事务已经提交的修改

set global transaction isolation level read committed;

同样开启事务A和事务B两个事务,在同一事务中(本例中的事务B),事务的不同时刻同样的查询条件,查询出来的记录内容是不一样的,事务A的提交影响了事务B的查询结果,这就是不可重复读,也就是读提交隔离级别。

读提交解决了脏读的问题,但是无法做到可重复读,也没办法解决幻读。

可重复读

保证同一个事务中多次读取的数据是一致的

set global transaction isolation level repeatable read;

首先看一下可重复读的效果,事务A启动后修改了数据,并且在事务B之前提交,事务B在事务开始和事务A提交之后两个时间节点都读取的数据相同,已经可以看出可重复读的效果。

可重复读做到了,这只是针对已有行的更改操作有效,但是对于新插入的行记录,就没这么幸运了,幻读就这么产生了。我们看一下这个过程:

事务A开始后,执行 update 操作,将 age = 1 的记录的 name 改为“风筝2号”;

事务B开始后,在事务执行完 update 后,执行 insert 操作,插入记录 age =1,name = 古时的风筝,这和事务A修改的那条记录值相同,然后提交。

事务B提交后,事务A中执行 select,查询 age=1 的数据,这时,会发现多了一行,并且发现还有一条 name = 古时的风筝,age = 1 的记录,这其实就是事务B刚刚插入的,这就是幻读。

要说明的是,当你在 MySQL 中测试幻读的时候,并不会出现上图的结果,幻读并没有发生,MySQL 的可重复读隔离级别其实解决了幻读问题,这会在后面的内容说明

串行化

并发事务之间是串行化的,通常意味着读取需要获取共享读锁,更新需要获取排他写锁,如果 SQL 使用 WHERE 语句,还会获取区间锁(MySQL 以 GAP 锁形式实现,可重复读级别中默认也会使用),这是最高的隔离级别。


MySQL 中是如何实现事务隔离的

首先说读未提交,它是性能最好,也可以说它是最野蛮的方式,因为它压根儿就不加锁,所以根本谈不上什么隔离效果,可以理解为没有隔离。

再来说串行化。读的时候加共享锁,也就是其他事务可以并发读,但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发读。

最后说读提交和可重复读。这两种隔离级别是比较复杂的,既要允许一定的并发,又想要兼顾的解决问题。

实现可重复读

为了解决不可重复读,或者为了实现可重复读,MySQL 采用了 MVVC (多版本并发控制) 的方式。

我们在数据库表中看到的一行记录可能实际上有多个版本,每个版本的记录除了有数据本身外,还要有一个表示版本的字段,记为 row trx_id,而这个字段就是使其产生的事务的 id,事务 ID 记为 transaction id,它在事务开始的时候向事务系统申请,按时间先后顺序递增。

按照上面这张图理解,一行记录现在有 3 个版本,每一个版本都记录这使其产生的事务 ID,比如事务A的transaction id 是100,那么版本1的row trx_id 就是 100,同理版本2和版本3。

在上面介绍读提交和可重复读的时候都提到了一个词,叫做快照,学名叫做一致性视图,这也是可重复读和不可重复读的关键,可重复读是在事务开始的时候生成一个当前事务全局性的快照,而读提交则是每次执行语句的时候都重新生成一次快照。

对于一个快照来说,它能够读到那些版本数据,要遵循以下规则:

  1. 当前事务内的更新,可以读到;
  2. 版本未提交,不能读到;
  3. 版本已提交,但是却在快照创建后提交的,不能读到;
  4. 版本已提交,且是在快照创建前提交的,可以读到;

利用上面的规则,再返回去套用到读提交和可重复读的那两张图上就很清晰了。还是要强调,两者主要的区别就是在快照的创建上,可重复读仅在事务开始是创建一次,而读提交每次执行语句的时候都要重新创建一次。


当前读和快照读的概念

(MYSQL数据库所有的数据操作,都会分为快照读和当前读)

当前读:像select lock in share mode( 共享锁),select for update ; update, insert ,delete( 排他锁) 这些操作都是⼀种当前读,为什么叫当前读? 就是它读取的是 记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进⾏加锁。

快照读:像不加锁的select 操作就是快照读,即不加锁的非阻塞读;  通过MVVC原理实现

快照读的前提是隔离级别是可重复读,因为读提交总是读取最新的数据行,而不是符合当前事务版本的数据⾏。而串行化则会对所有读取的行都加锁

[事务] 事务的隔离级别相关推荐

  1. 脏读、不可重复读 共享锁、悲观锁 和 事务五种隔离级别

    http://www.cnblogs.com/adforce/archive/2011/04/20/2021929.html 一.脏读.不可重复读.幻读 1.脏读:脏读就是指当一个事务正在访问数据,并 ...

  2. MySQL 之事务 及 其隔离级别

    MySQL 之事务 及 其隔离级别 /* 事务:表示一组操作(sql),要么同时成功,要么同时失败,那么这种操作就构成了一个事务. 例如: 张三 给 李四 转账 500元 (1)把张三的余额减少500 ...

  3. 《MySQL》入门基础知识点大全:数据库操作、增删改查、联表查询、常用函数、MD5加密、事务特性、隔离级别

    MySQL基础知识大全 1.操作数据库 1.1 创建表 1.2 修改表名 1.3 增加表的字段 1.4 修改表的字段 1.4.1 修改表的字段 1.4.2 修改表名 1.5 删除表的字段 1.6 删除 ...

  4. MySql事务4种隔离级别以及悲观锁和乐观锁

    前言:在那鬼公司呆着发现自己居然把事务给搞明白了. 缘由:公司做的一个项目在进行首页内容显示的时候发现查询结果特别慢,有时候需要一到五分钟才能显示出结果.于是乎,我就顺着SQL语句查询慢的原因找了下去 ...

  5. 一文彻底读懂MySQL事务的四大隔离级别

    前言 之前分析一个死锁问题,发现自己对数据库隔离级别理解还不够深入,所以趁着这几天假期,整理一下MySQL事务的四大隔离级别相关知识,希望对大家有帮助~ 事务 什么是事务? 事务,由一个有限的数据库操 ...

  6. MySQL事务原理之事务概述和隔离级别

    MySQL事务概述和隔离级别 事务 事务的特征 事务的控制语句 事务的生命周期 事务执行过程 ACID特性 原子性(A) 一致性(C) 隔离性(I) 持久性(D) 隔离级别 命令 不同隔离级别并发异常 ...

  7. 事务默认的传播属性和事务默认的隔离级别

    事务的传播属性 事务的隔离级别,用的就是当前数据的隔离级别

  8. mysql spring隔离级别_MySQL事务与Spring隔离级别实现

    1.事务具有ACID特性 原子性(atomicity):一个事务被事务不可分割的最小工作单元,要么全部提交,要么全部失败回滚. 一致性(consistency):数据库总是从一致性状态到另一个一致性状 ...

  9. 数据库 之 事务控制和隔离级别

    1  概述 事务是指一组原子性的SQL查询.或者是一个或多个SQL语句组成的独立工作单元:MyISAM不流行的原因很大是因为其不支持事务的处理功能. 2  事务日志 事务日志定义属性,有些参数可以运行 ...

  10. spring 事物的级别_Spring 事务中的隔离级别有哪几种?

    答: TransactionDefinition 接口中定义了五个表示隔离级别的常量: 1.TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级 ...

最新文章

  1. 80m的mysql文件要导入多久_mysql导入导出数据库的问题
  2. xml之结构(company-employ buyer)
  3. Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network
  4. Karrigell介绍
  5. github 搜索_Fzf:Golang开发的Github高星系统模糊搜索补全工具
  6. windows python安装opencv_OpenCV开发(1)——OpenCV3.4+Python3.5+Windows10安装问题解决
  7. Velocity.js中文文档
  8. Dottext.Web.UI.Handlers.BlogExistingPageHandler
  9. leetcode43. 字符串相乘 经典大数+和*
  10. TensorFlow 基本使用
  11. 【月薪三万】听说深圳老师工资全国最高!!!比德国还高
  12. Hive 数据质量检测
  13. 如何用php开启企业微信开发的回调模式
  14. lammps教程:Ovito中多晶不同颜色显示技巧
  15. 嵌入式C语言入门操作
  16. adobe ae cs6中文版汉化(11.02)win版汉化安装教程
  17. extmail mysql数据库 重启_配置extmail过程详解 | 学步园
  18. 用wget命令整站下载
  19. 【转】redis利用姿势收集
  20. 计算机画图照片大小,电脑自带的画图工具怎么调整图片的大小?

热门文章

  1. 会编程语言的程序员学习SEO有优势吗?
  2. 电脑维护最经常问的N个问题
  3. 音视频基础:字幕篇(SSA和ASS)
  4. 计算机组装如何连接控制面板,笔记本计算机组装图形教程_生活与休闲
  5. 《树莓派实战秘籍》——1.8 技巧08获取更多的USB端口
  6. 【思考】百度all in人工智能,是要得道成仙还是走火入魔?
  7. POJ1716-Integer Intervals
  8. 形容时间过得快的名言名句有哪些
  9. 关于subprocess.Popen无法执行
  10. QT主界面卡死崩溃解决(5种方法)