在《数据库事务》有一节介绍了MySQL事务的四大特性(ACID:原子性-Atomicity,一致性-Consistency,隔离性-lsolation,持久性-Durability),其中事务的隔离性就是指当多个事务同时运行时,各事务之间相互隔离,不可互相干扰。如果事务没有隔离性,就容易出现脏读、不可重复读和幻读等情况。
为了保证并发时操作数据的正确性,数据库都会有事务隔离级别的概念。
- 脏读
脏读是指一个事务正在访问数据,并且对数据进行了修改,但是这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
2. 不可重复读
不可重复读是指在一个事务内,多次读取同一个数据。在这个事务还没有结束时,另外一个事务也访问了该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
3. 幻读
幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还没有修改的数据行,就好像发生了幻觉一样。
为了解决以上这些问题,标准SQL定义了4类事务隔离级别,用来指定事务中的哪些数据改变是可见的,哪些数据改变是不可见的。
MySQL包括的事务隔离级别如下:
- 读未提交(READ COMMITTED)
- 读提交(READ COMMITTED)
- 可重复读(REPEATABLE READ)
- 串行化(SERIALIZABLE)
MySQL事务隔离级别可能产生的问题如下表所示:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
| READ UNCOMMITTED | √ | √ | √ |
| READ COMMITTED | × | √ | √ |
| REPEATABLE READ | × | × | √ |
| SERIALIZABLE | × | × | × |
MySQL的事务的隔离级别由低到高分别为READ UNCOMITTED,READ COMMMITTED,REPEATABLE READ,SERIALIZABLE。低级别的隔离级别可以支持更高的并发处理,同时占用的系统资源更少。
下面根据实例来一一阐述他们的概念和联系。
1. 读未提交(READ UNCOMMITTED,RU)
读未提交就是可以读到未提交的内容。
如果一个事务读到了另一个未提交的事务修改过的数据,那么这种隔离级别就称之为读未提交。
在该隔离级别下,所有事务都可以看到其他未提交事务的执行结果,因为他的心梗与其他隔离级别相比没有高多少,所以在一般情况下,该隔离级别在实际应用中很少使用。
实例:
1.1 打开窗口A,登陆mysql
1.2 打开窗口B,登陆mysql
1.3 分别查询A,B两个窗口的隔离级别
select @@transaction_isolation;
1.4 分别设置A,B两个窗口的隔离级别,保证两个事务的隔离级别相同。
set session transaction isolation level read uncommitted;
1.5 设置A窗口中开启事务(开启事务,就相当于不自动提交),并查询
begin;
select
1.6 在B窗口,确定事务隔离级别是 READ-UNCOMMITTED 后,开启一个事务。
2. 读提交(READ COMMITTED,RC)
读提交就是只能读到已经提交了的内容。
如果一个事务只能读取到另一个已提交事务修改过的数据,并且其它事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值,那么这种隔离级别就称之为读提交。
该隔离级别满足了隔离的简单定义:一个事务从开始到提交前所做的任何改变都是不可见的,事务只能读取到已经提交的事务所做的改变。
这是大多数数据库系统的默认事务隔离级别(例如 Oracle、SQL Server),但不是 MySQL 默认的。



