Mysql事务-隔离级别
MYSQL事务-隔离级别
事务是什么?
事务简言之就是一组SQL执行要么全部成功,要么全部失败。MYSQL的事务在存储引擎层实现。
事务都有ACID特性:
原子性(Atomicity):一个事务必须被视为一个不可分割的单元;
一致性(Consistency):数据库总是从一种状态切换到另一种状态;
隔离性(Isolation):通常来说,事务在提交前对于其他事务不可见;
持久性(Durablity):一旦事务提交,所做修改永久保存数据库;
事务最常用的例子就是银行转账。假设polo需给lynn转账1000元,如下步骤:
确认polo账户余额高于1000元;
从polo的账户余额减去1000元;
将lynn的账户余额增加1000元;
SQL语句如下:
mysql> BEGIN;
mysql> SELECT balance FROM bank_account WHERE uid=10001;
mysql> UPDATE bank_account SET balance=balance-1000 WHERE uid=10001;
mysql> UPDATE bank_account SET balance=balance+1000 WHERE uid=10002;
mysql> COMMIT;
注:mysql启动事务可使用BEGIN或者START TRANSACTION;
上述三个步骤执行在一个事务中就能够保证数据的完整性,要么全部成功,要么全部失败。
MYSQL提供两种事务型引擎:Innodb和NDBCluster。默认采用自动提交模式,执行一条语句自动COMMIT。通过AUTOCOMMIT变量可启用或者禁用自动提交模式:
mysql> SHOW VARIABLES LIKE "AUTOCOMMIT";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.00 sec)
mysql> SET AUTOCOMMIT=1
AUTOCOMMIT=1表示开启默认提交,0表示关闭默认提交需要手动提交。
事务隔离级别
事务隔离性的解释:通常情况下,事务在提交之前对于其他事务不可见。
数据库有四种隔离级别,当然MYSQL也是如此。分别为:
READ UNCOMMITED(未提交读)
READ COMMITED(已提交读)
EPEATABLE READ(可重复读)
SEAIALIZABLE(可串行化)
本人理解 : 隔离级别就是决定一个事务的修改另一个事务什么情况下可见。
书本解释 : 隔离级别都规定了一个事务中所做修改,哪些在事务内和事务间是可见的。
上面两段理解的区别在于是否存在事务内可见性的规定。我在各个级别似乎没有看到
下面开始说明MYSQL的四种隔离级别,先准备一张学生表:
mysql> CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
只有id(主键自增)与name字段
READ UNCOMMITTED(未提交读)
事务中修改没有提交对其他事务也是可见的,俗称脏读。非常不建议使用。
实例演示
客户端A和B设置隔离级别为未提交读
mysql> SET SESSION TX_ISOLATION='READ-UNCOMMITTED';
客户端A与B开启事务并查询student
mysql> BEGIN;
mysql> SELECT * FROM student;
Empty set (0.00 sec)客户端A和B都是空数据
客服端B插入一条新的数据
mysql> INSERT INTO student(name) VALUES("polo");
Query OK, 1 row affected (0.00 sec)此时事务未提交,客服端A查看student表
$ SELECT * FROM student;
mysql> SELECT * FROM student;
+----+------+
| id | name |
+----+------+
| 1 | polo |
+----+------+
1 row in set (0.00 sec)客户端A看到B未提交的修改
客户端B执行回滚操作
mysql> ROLLBACK
成功之后,客户端A查看student表
mysql> SELECT * FROM student;
Empty set (0.00 sec)客户端A查看数据为空
以上可以看出未提交读隔离级别的危险性,对于一个没有提交事务所做修改对另一个事务是可见状态,容易造成脏读。非特殊情况不得使用此级别
READ COMMITTED(提交读)
多数数据库系统默认为此级别(MYSQL不是)。已提交读级别即为一个事务只能已提交事务所做的修改,也就解决了未提交读的问题,即脏读的问题。实例演示
客户端A和B设置隔离级别为已提交读
mysql> SET SESSION TX_ISOLATION='READ-COMMITTED';
客户端A与B开启事务并查询student
mysql> BEGIN;
mysql> SELECT * FROM student;
Empty set (0.00 sec)客户端A和B都为空
客服端B插入一条新的数据,不提交
mysql> INSERT INTO student (name) VALUES('polo');
客户端A查看student
mysql> SELECT * FROM student;
Empty set (0.00 sec)注意这里与上面不同了,在客户端B没有提交事务情况下无数据
下面客户端B提交事务
mysql> COMMIT;
客户端A再次查看student表。
mysql> SELECT * FROM student;
+----+------+
| id | name |
+----+------+
| 1 | polo |
+----+------+
1 row in set (0.00 sec)成功读取到客户
从上面的示例可以看出,提交读没有了未提交读的问题,但我们可以看到在客户端A的一个事务中执行两次同样的SELECT语句得到不同结果,因此已提交读又被称为不可重复读。同样筛选条件可能得到不同的结果。
REPEATABLE READ(可重复读)
如其名也,解决已提交读不可重复读取的问题。
示例演示
客户端A和B设置隔离级别为可重复读
mysql> SET SESSION tx_isolation='REPEATABLE-READ'
客户端A与B开启事务并查看
mysql> BEGIN;
mysql> SELECT * FROM student;
+----+------+
| id | name |
+----+------+
| 1 | polo |
+----+------+
1 rows in set (0.00 sec)客服端B更新polo为jeff,并提交事务
mysql> UPDATE student SET name='jeff' WHERE id=1;
mysql> COMMIT客户端A查看student表
mysql> SELECT * FROM student;
+----+------+
| id | name |
+----+------+
| 1 | jeff |
+----+------+
1 rows in set (0.00 sec)注意客户端A查看数据未变,没有不可重复读问题
客户端A提交事务,并查看student表
mysql> COMMIT;
mysql> SELECT * FROM student;
+----+------+
| id | name |
+----+------+
| 1 | polo |
+----+------+
1 rows in set (0.00 sec)上面实例可知,可重复读两次读取内容一样。数据库这级别并没有解决幻读的问题。但是MYSQL在可重复读基础上增加了MVCC机制解决了此问题,实例无法演示幻读效果。
那什么是幻读?首先,可重复读锁定范围为当前查询到的内容,如执行
mysql> SELECT * FROM student WHERE id>=1
锁定的即id>=1查到的行,为行级锁。如另一事务执行并默认提交以下语句
mysql> INSERT INTO student (name) VALUES ('peter');
新增的这行并没有被锁定,此时读取student
mysql> SELECT * FROM student WHERE id>=1;
+----+---------+
| id | name |
+----+---------+
| 1 | polo |
| 2 | peter |
+----+---------+
2 rows in set (0.00 sec)便出现了幻读
除了使用MYSQL的MVCC机制,还可以使用可串行化隔离级别解决此问题。
SEAIALIZABLE(可串行化)
可串行化是最高隔离级别,强制事务串行执行。执行串行了也就解决了一切的问题,这个级别只有在对数据一致性要求非常严格且没用并发的情况下使用
实例演示
客户端A和B设置隔离级别为可串行化
mysql> SET SESSION tx_isolation='SERIALIZABLE';
客户端A执行查询
mysql> SELECT * FROM student WHERE id<4;
+----+---------+
| id | name |
+----+---------+
| 1 | polo |
| 2 | peter |
+----+---------+
2 rows in set (0.00 sec)客户端B执行新增
mysql> INSERT INTO student (name) VALUES('tiger');
好的!效果出现了,此时我们会发现INSERT语句被阻塞执行,原因就是A执行了查询表student同时满足id<4,已被锁定。如果查询表student条件为id<3,则新增语句可正常执行。
隔离级别对照图
Mysql事务-隔离级别的更多相关文章
- [51CTO]新说MySQL事务隔离级别!
新说MySQL事务隔离级别! 事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!本文所讲大部分内容,皆有官网作为佐证,因此对本文内 ...
- 查询mysql事务隔离级别
查询mysql事务隔离级别 查询mysql事务隔离级别 分类: DB2011-11-26 13:12 2517人阅读 评论(0) 收藏 举报 mysqlsessionjava 1.查看当前会话隔离 ...
- MySQL事务隔离级别测试实例
https://www.cnblogs.com/huanongying/p/7021555.html MySQL事务隔离级别 事务隔离级别 脏读 不可重复读 幻读 读未提交(read-uncommit ...
- MySQL事务隔离级别 解决并发问题
MySQL事务隔离级别 1. 脏读: 骗钱的手段, 两个窗口或线程分别调用数据库转账表,转账后未提交,对方查看到账后,rollback,实际钱没转. 演示方法: mysql默认的事务隔离级别为repe ...
- mysql事务隔离级别、脏读、幻读
Mysql事务隔离级别本身很重要,再加上可能是因为各大公司面试必问的缘故,在博客中出现的概率非常高,但不幸的是,中国的技术博客要么是转载,要么是照抄,质量参差不齐,好多结论都是错的,对于心怀好奇之心想 ...
- mysql事务隔离级别与设置
mysql数据库,当且仅当引擎是InnoDB,才支持事务: 1.隔离级别 事务的隔离级别分为:未提交读(read uncommitted).已提交读(read committed).可重复读(repe ...
- MySQL事务隔离级别(二)
搞清楚MySQL事务隔离级别 首先创建一个表 account.创建表的过程略过(由于 InnoDB 存储引擎支持事务,所以将表的存储引擎设置为 InnoDB).表的结构如下: 为了说明问题,我们打开两 ...
- MySQL事务隔离级别(一)
本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做 ...
- 面试突击61:说一下MySQL事务隔离级别?
MySQL 事务隔离级别是为了解决并发事务互相干扰的问题的,MySQL 事务隔离级别总共有以下 4 种: READ UNCOMMITTED:读未提交. READ COMMITTED:读已提交. REP ...
随机推荐
- mac下更新自带的PHP版本到5.6或7.0
下载和安装PHP 5.6 打开终端并且运行如下命令: curl -s http://php-osx.liip.ch/install.sh | bash -s 5.6 然后,PHP 5.6的版本会被安装 ...
- cmd不是内部命令解决方法
当进入cmd之后,经常会出现这样的提示“不是内部命令”等,给一些习惯使用cmd排查故障的IT管理员带来了困扰,现将解决方法介绍一下,希望能帮助你. 1.看看你机子里的 c:\windows\syste ...
- solr copyfield字段使用实践
1.使用场景 比如我们现在有一个文档,有title.author.area.keyword.link等字段.现在要把这个文档索引到 solr中,为了方便对author.area.keyword进行搜索 ...
- win7上搭建ruby开发环境
1. 安装ruby 可使用windows下的ruby安装工具rubyinstaller来方便地安装ruby解释器,可以http://rubyinstaller.org/网站上下载得到.安装时,看清安装 ...
- angular directive 深入理解
由于业务的需要,最近angular 的diretive 研究的比较多,有和同事一起共同协作开发scada的项目, 对directive 有了进一步更深的理解. 感觉才开始真正理解了这句话的意思: In ...
- Win10 无法用内置管理员帐户打开 解决方案
- [Android] 给图像加入相框、圆形圆角显示图片、图像合成知识
前一篇文章讲述了Android触屏setOnTouchListener实现突破缩放.移动.绘制和加入水印,继续我的"随手拍"项目完毕给图片加入相框.圆形圆角显示图片和图像合 ...
- POJO百度百科
POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称. 使用POJO名称是为了避免和EJB混淆起来, ...
- zoj 2744 - Palindromes
题目:统计一个串中的回文子串的个数(注意是子串,要连续). 分析:dp.暴力.直接用dp,二维数组内存不够用,并且dp木有暴力快( ⊙ o ⊙ )啊! 说明:(2011-09-24 03:22). # ...
- iOS 核心动画 Core Animation浅谈
代码地址如下:http://www.demodashi.com/demo/11603.html 前记 关于实现一个iOS动画,如果简单的,我们可以直接调用UIView的代码块来实现,虽然使用UIVie ...