MySQL事务(脏读、不可重复读、幻读)
1. 什么是事务?
是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元);
2.事务的四大特性ACID
一个事务往往具有一下特性:
原子性(ATOMICITY):
一个事务要被完全的无二义性的做完或撤消。在任何操作出现一个错误的情况下,构成事务的所有操作的效果必须被撤消,数据应被回滚到以前的状态。
一致性(CONSISTENCY):
一个事务应该保护所有定义在数据上的不变的属性(例如完整性约束)。在完成了一个成功的事务时,数据应处于一致的状态。换句话说,一个事务应该把系统从一个一致-状态转换到另一个一致状态。举个例子,在关系数据库的情况下, 一个一致的事务将保护定义在数据上的所有完整性约束。
隔离性(ISOLATION):
在同一个环境中可能有多个事务并发执行,而每个事务都应表现为独立执行。串行的执行一系列事务的效果应该同于并发的执行它们。这要求两件事:
在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。
两个并发的事务应该不能操作同一项数据。数据库管理系统通常使用锁来实现这个特征。
持久性(DURABILITY):
一个被完成的事务的效果应该是持久的。
3.创建事务的SQL语法
隐式事务:事务没有明显的开启或者结束的标志,在mysql中,默认是开启自动提交的
SHOW @@autocommit;
所以针对SELECT、UPDATE、DELETE、INSERT等DQL及DML语句的执行,mysql会自动提交该事务,如果关闭就需要手动提交或者回滚来完成操作。
显式事务:与隐式事务想反,有明显的开启或结束标志。
SET autocommit=0
[START TRANSACTION] # 可选的语句
[DELETE | UPDATE | INSERT | SELECT ] # DML、DQL操作
[COMMIT | ROLLBACK]; #提交或者回滚
可以看出,在事务未结束之前,操作是有效的且更改了数据实体,那么试想一下,如果这是有多个事务参与, 肯定会出现各种各样的数据不统一的情况,这就类似多个线程在没有锁的情况下修改同一个全局变量。
显式事务:回滚点的使用(setpoint)
SET AUTOCOMMIT=0;
START TRANSACTION;
[DELETE | UPDATE | INSERT | SELECT]; #回滚时要执行提交的部分
SAVEPOINT a; # 设置回滚点,且变量名为a
[DELETE | UPDATE | INSERT | SELECT]; #回滚时不执行提交的部分
ROLLBACK TO a; # 回滚时与ROLLBACK TO搭配使用
可以发现在回滚点以前的数据实体被删除、之后的数据实体因为回滚而被撤销操作。
注意:在事务中使用truncate时,就算rollback也会清空整张表
4.多个事务在不同事务隔离级别下的并发问题
在mysql下事务的隔离级别有四种且由低到高依次为Read uncommitted 、Read committed 、Repeatable read (默认)、Serializable ,这四个级别中的后三个级别可以逐个解决脏读 、不可重复读 、幻读这几类问题
1. 脏读的情况:对于两个事务T1与T2,T1读取了已经被T2更新但是还没有提交的字段之后,若此时T2回滚,T1读取的内容就是临时并且无效的
开启两个mysql客户端,并创建一张测试表transaction
更改默认隔离级别REPEATABLE READ为READ UNCOMMITTED
SELECT @@tx_isolation; #查询隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; # 更改隔离级别
两个客户端同时开启事务,其中一个事务做UPDATE操作,另一个事务做SELECT
若此时黑色背景的客户端进行回滚,则白色背景的客户端读取的数据就是临时并且无效的。即脏读。
2. 不可重复读: 对于两个事务T1和T2,T1读取了一个字段,然后T2更新了该字段并提交之后,T1再次提取同一个字段,值便不相等了。
重复读取的结果不一致的情况发生。
3. 幻读: 对于两个事务T1、T2,T1从表中读取数据,然后T2进行了INSERT操作并提交,当T1'再次读取的时候,结果不一致的情况发生。
5. 不同隔离级别所解决的事务并发问题
脏读 | 不可重复读 | 幻读 | |
READ UNCOMMITTED | 1 | 1 | 1 |
READ COMMITTED | 0 | 1 | 1 |
REPEATABLE READ | 0 | 0 | 1 |
SERIALIZABLE | 0 | 0 | 0 |
READ UNCOMMITTED级别不做演示,其隔离性最低,会出现脏读、不可重复读、幻读等所有情况。
READ COMMITTED级别能够避免脏读,下面来进行演示:
1.避免脏读(一个事务读取到另一个事务未提交的数据)
2. 无法避免重复读(一个事务读取到另一个事务已经提交的数据)
REPEATABLE READ避免不可重复读的情况发生,下面来看演示:
1. 避免不可重复读(一个事务读取到另一个事务已经提交的数据)
2. 无法避免幻读(一个事务多次查询整表数据,由于其他事务新增(删除)记录造成多次查询的记录条数不同(一个事务读取到另一个事务已经提交的数据))
SERIALIZABLE避免幻读情况,阻塞方式
可以看出,serializable级别就类似加锁的方式,同一时刻支持多个事务并发,但是针对DML(UPDATE\INSERT\DELETE)操作时,当前发起操作的事务会被阻塞,直到其他事务commit或者rollback才会继续执行事务语句。可见效率十分低下。
MySQL事务(脏读、不可重复读、幻读)的更多相关文章
- 数据库事务隔离级别 - 分析脏读 & 不可重复读 & 幻读
一 数据库事务的隔离级别 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted .Read committed .Repeatable read .Serializable ,这 ...
- MYSQL事件隔离级别以及复读,幻读,脏读的理解
一.mysql事件隔离级别 1未提交读(READUNCOMMITTED) 另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据(脏读)( 隔离级别最低,并发性能高 ) 2 ...
- spring事务隔离级别以及脏读 不可重复读 幻影读
隔离级别 声明式事务的第二个方面是隔离级别.隔离级别定义一个事务可能受其他并发事务活动活动影响的程度.另一种考虑一个事务的隔离级别的方式,是把它想象为那个事务对于事物处理数据的自私程度. 在一个典型的 ...
- Java -- JDBC 事务处理, 事务的隔离级别 脏读 不可重复读 等...
1. 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 数据库开启事务命令 •start transaction 开启事务 •Rollback 回滚事务 •Commit ...
- MySQL 笔记整理(20) --幻读是什么,幻读有什么问题?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 20) --幻读是什么,幻读有什么问题? 我们先来看看表结构和初始化数据 ...
- InnoDB在MySQL默认隔离级别下解决幻读
1.结论 在RR的隔离级别下,Innodb使用MVVC和next-key locks解决幻读,MVVC解决的是普通读(快照读)的幻读,next-key locks解决的是当前读情况下的幻读. 2.幻读 ...
- Mysql事务开启方式(客户端+java手动+Spring Boot)
一:概念 作为单个逻辑单元执行一系列操作,要么完全执行,要么完全不执行.举例 我们需要向数据库插入3条数据(我们希望这三条数据要么全部插入成功,要么全部失败), 比如第一条数据插入成功,插入第二条数据 ...
- Mysql事务,并发问题,锁机制-- 幻读、不可重复读--专题
1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库正确地改变状态后,数据库的一致性约 ...
- 第七章 mysql 事务索引以及触发器,视图等等,很重要又难一点点的部分
[索引] 帮助快速查询 MyISAM ,InnoDB支持btree索引 Memory 支持 btree和hash索引 存储引擎支持 每个表至少16个索引 总索引长度至少256字节 创建索引的优 ...
随机推荐
- ubuntu安装mysql数据库方法
ubuntu基于linux的免费开源桌面PC操作系统,十分契合英特尔的超极本定位,支持x86.64位和ppc架构.一个比较流行的Linux操作系统,不仅简单易用,而且和Windows相容性非常好.那么 ...
- 笔谈FFmpeg(一)
现在的工作是播放器库的开发,可不是调用iOS系统自带的播放器框架进行一些简单的功能和界面定制,这些没什么含量.涉及iOS开发有3个年头了,现在的工作算是有点含金量了.涉及播放器的开发,FFmpeg的架 ...
- jenkins 启动
docker pull jenkinsci/blueocean docker run \ -u root \ --rm \ -d \ -p 8888:8080 \ -p 50000:50000 \ - ...
- Elasticsearch 是什么
Elasticsearch 是什么 Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎.无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进.性能最好的.功 ...
- 系统调用IO和标准IO
目录 1. 系统调用IO(无缓冲IO) 系统调用 常用系统调用IO函数 open close read write lseek ioctl 2. 标准IO(带缓冲IO) 概述 缓冲与冲洗 常用标准IO ...
- 2013.4.30 - KDD第十二天
早上来实验室,本来打算向秦师兄要文献的,不过秦师兄上午不在,所以就没有联系他.于是就开始调试郑茂的代码,发现原来那个itoa函数不是标准库里面 的,所以可能只有windows上可以用.然后我就在打电脑 ...
- Docker——概念学习
百度百科概念: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化.容器是完全 ...
- LOJ129 Lyndon 分解
Lyndon 分解 样例 样例输入 1 ababa 样例输出 1 2 4 5 样例输入 2 bbababaabaaabaaaab 样例输出 2 1 2 4 6 9 13 18 样例输入 3 azAZ0 ...
- 详解C++中基类与派生类的转换以及虚基类
很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中 ...
- Vue创建组件的三种方式
1.使用 Vue.extend 来创建全局的Vue组件 <div id="app"> <!-- 如果要使用组件,直接,把组件的名称,以 HTML 标签的形式,引入 ...