五分钟后,你将真正理解MySQL事务隔离级别!

什么是事务?
事务是一组原子性的SQL操作,所有操作必须全部成功完成,如果其中有任何一个操作因为崩溃或其他原因无法执行,那么所有的操作都不会被执行。也就是说,事务内的操作,要么全部执行成功,要么全部执行失败。
事务的结束有两种,当事务中的所有操作全部成功执行时,事务提交。如果其中一个操作失败,将发生回滚操作,撤消之前到事务开始时的所有操作。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
事务的特性
一个运行良好的事务处理系统,还需要具备四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持续性(Durability)。这四个特性简称为ACID特性。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
原子性(Atomicity)
一个事务必须被视为一个不可分割的最小逻辑工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。对于一个事务来说,不可能只执行其中的一部分操作,而不执行其中的另外一部分操作,这就是事务的原子性。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
一致性(Consistency)
事务执行的结果必须是从一个一致性的状态转换到另外一个一致性的状态。当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果事务因为崩溃或其他原因尚未完成,被迫中断最终事务没有提交,那么事务中所做的修改也不会保存到数据库中。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
隔离性(Isolation)
通常来说,一个事务的执行不能其它事务干扰。也就是说,一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。后面我们将要讲解隔离级别(Isolation Level)的时候,会发现为什么我们要说“通常来说”是隔离的。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
持续性(Durability)
事务一旦提交,它对数据库中的数据的修改就应该是永久性的。此时即使系统崩溃,修改的数据也不会丢失。不过,实际上持久性也分很多不同的级别,有些持久性策略能够提供非常强的安全保障,而有些则未必。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
事务隔离级别
在SQL标准中定义了四种隔离级别,每一种级别都定义了一个事务所做的修改,在另外一个事务内和事务间,哪些是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
未提交读(Read Uncommitted)
在未提交读级别中,事务中的修改即使没有提交,对其他事务也是可见的。读取到了事务没有提交的数据,就被成为脏读(Dirty Read)。事务没有提交的数据是很“脏”的,被读取到会引起很多问题。从性能角度上看,未提交读级别不会比其他级别好很多,但缺乏其他级别的好处,所以在实际应用中很少被用到。
为加上深对未提交读级别的理解,让我们看一个脏读的例子,首先设置事务隔离级别为未提交读:
mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
再检验一下事务隔离级别:
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set, 1 warning (0.00 sec)
左右分别为两个用户,左边是用户A,右边是用户B,时间线从上至下:
#用户A:查询user表,有一条OneMoreStudy的记录
mysql> select * from user;
+----+--------------+
| id | name |
+----+--------------+
| 1 | OneMoreStudy |
+----+--------------+
1 row in set (0.00 sec)
#用户B:开始事务
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
#用户B:更新user表的一条记录
mysql> update user set name = 'OMS' where id = 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
#用户A:查询user表,有一条OMS的记录,脏读
mysql> select * from user;
+----+------+
| id | name |
+----+------+
| 1 | OMS |
+----+------+
1 row in set (0.00 sec)
#用户B:提交事务
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
提交读(Read Committed)
在提交读级别中,一个事务开始时,只能查询到其他的事务已经提交的修改。也就是说,一个事务从开始到提交之前,任何的修改对其他的事务都是不可见的。提交读级别基本满足了事务的隔离性。
不过,在同一事务中两次查询之间,有其他事务的修改被提交,那么两次查询到结果可能不相同,这就是不可重复读。
为了更好的理解不可重复读,让我们看一个例子,首先设置事务隔离级别为提交读:
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
再检验一下事务隔离级别:
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set, 1 warning (0.00 sec)
左右分别为两个用户,左边是用户A,右边是用户B,时间线从上至下:
#用户A:开始事务
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
#用户A:查询user表,有一条OneMoreStudy的记录
mysql> select * from user;
+----+--------------+
| id | name |
+----+--------------+
| 1 | OneMoreStudy |
+----+--------------+
1 row in set (0.00 sec)
#用户B:更新user表的一条记录
mysql> update user set name = 'OMS' where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
#用户A:查询user表,有一条OMS的记录,不可重复读
mysql> select * from user;
+----+------+
| id | name |
+----+------+
| 1 | OMS |
+----+------+
1 row in set (0.00 sec)
#用户A:提交事务
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
可重复读(Repeatable Read)
在可重复读级别中,保证了在同一个事务中多次读取同样记录的结果是一致的。即使多次读取之间有其他事务对其结果做了修改,同一个事务中多次读取的结果也是一致的。可重复读级别也是MySQL的默认事务隔离级别。
不过,当一个事务在读过某个范围内的记录时,其他事务又在这个范围内插入了新的记录,当之前的事务再一次读取这个范围的记录时,不会读取到新插入的那条记录,这被称为幻读。
为了更好的理解幻读,让我们看一个例子,首先把事务隔离级别设置为可重复读:
mysql> set session transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)
再检验一下事务隔离级别:
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)
左右分别为两个用户,左边是用户A,右边是用户B,时间线从上至下:
#用户A:开始事务
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
#用户A:查询user表,有一条记录
mysql> select * from user;
+----+--------------+
| id | name |
+----+--------------+
| 1 | OneMoreStudy |
+----+--------------+
1 row in set (0.00 sec)
#用户B:插入一条数据
mysql> insert into user (name) value ('OneMoreStudy');
Query OK, 1 row affected (0.01 sec)
#用户A:查询user表,还是一条记录,幻读
mysql> select * from user;
+----+--------------+
| id | name |
+----+--------------+
| 1 | OneMoreStudy |
+----+--------------+
1 row in set (0.00 sec)
#用户A:提交事务
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
#用户A:查询user表,两条记录
mysql> select * from user;
+----+--------------+
| id | name |
+----+--------------+
| 1 | OneMoreStudy |
| 2 | OneMoreStudy |
+----+--------------+
2 rows in set (0.00 sec)
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
可串行化(Serializable)
在可串行化级别中,强制事务串行执行,是最高的隔离级别。在这个级别中,虽然避免了上面提到的幻读,但是会在读取的每一行上加锁,可能导致大量的超时和锁竞争问题,所以在实际应用中很少被用到。除非,非常需要确保数据一致性并且不要求高并发,可以采用可串行化级别。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
总结
本文首先简单介绍了事务及其ACID特性,然后着重讲解了事务的四种隔离级别:
- 未提交读:事务中的修改即使没有提交,对其他事务也是可见的。
- 提交读:事务开始时,只能查询到其他的事务已经提交的修改。
- 可重复读:保证在同一个事务中多次读取同样记录的结果是一致的。
- 可串行化:强制事务串行执行。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 未提交读 | 可能 | 可能 | 可能 |
| 提交读 | 不可能 | 可能 | 可能 |
| 可重复读 | 不可能 | 不可能 | 可能 |
| 可串行化 | 不可能 | 不可能 | 不可能 |
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
五分钟后,你将真正理解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事务-隔离级别 事务是什么? 事务简言之就是一组SQL执行要么全部成功,要么全部失败.MYSQL的事务在存储引擎层实现. 事务都有ACID特性: 原子性(Atomicity):一个事务必须被 ...
- 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):事务开始后所有操作,要么全部做完,要么全部不做 ...
随机推荐
- 16、python面对对象之类和继承
前言:本文主要介绍python面对对象中的类和继承,包括类方法.静态方法.只读属性.继承等. 一.类方法 1.类方法定义 使用装饰器@classmethod装饰,且第一个参数必须是当前类对象,该参数名 ...
- python应用airtest库的环境搭建
参考https://blog.csdn.net/ywyxb/article/details/64126927 注意:无论是在线还是离线安装,最好在管理员权限下执行命令 1.安装Python36(32位 ...
- WinSCP整合SecureCRT打开终端
使用WinSCP直接操作文件非常方便,但是如果用它来连入SSH进行指令交互就不方便了,使用XShell.SecureCRT.Putty等SSH终端软件敲指令却很不错,于是想能不能将两者结合起来使用.我 ...
- [ZJOI2008]树的统计(树链剖分)
[ZJOI2008]树的统计(luogu) Description 一棵树上有 n 个节点,编号分别为 1 到 n,每个节点都有一个权值 w.我们将以下面的形式来要求你对这棵树完成一些操作: I. C ...
- 三句话搞定FireDAC连接池
form上拖入: FDManager1: TFDManager; FDConnection1: TFDConnection; //初始化连接池procedure TForm1.InitDBPool;b ...
- 在Centos7上安装Oracle
环境: 硬盘30G:2G RAM:Centos7:Oracle 11G: 1.创建组和用户 [zzd@localhost ~]$ su root #切换到root Password: [root@lo ...
- 优雅地关闭worker进程
关闭nginx两种方式 nginx -s stop 立即停止nginx进程 nginx -s quit 优雅地关闭worker进程 开始优雅的关闭worker进程后 01设置定时器 worker_ ...
- ffmpeg常用数据结构
from :http://my.oschina.net/u/555701/blog/56748 AVCodecContext 这是一个描述编解码器上下文的数据结构,包含了众多编解码器需要的参数信息,如 ...
- 了解EBP指针
在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX用于记数等等.在win3 ...
- vcs/verdi filist
. 现在很多verilog 的filelist 文件中用如下形式来指定文件所在的目录就行了,而不必指定具体文件 ./testbench/ppc460_PLB4/p464s_test_top_tb.v ...