一、如何理解隔离性
MySQL 服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务方式进行。
一个事务可能由多条 SQL 构成,也就意味着,任何一个事务都有执行前、执行中、执行后的阶段。所谓的原子性,就是让用户层要么看到执行前,要么看到执行后。执行中出现问题,可以随时回滚。所以单个事务对用户表现出来的特性是原子性。
但所有事务都要有个执行过程,在多个事务各自执行多个 SQL 的时候,还是可能会出现互相影响的情况。比如:多个事务同时访问同一张表,甚至同一行数据。这就如同你妈妈给你说:你要么别学,要学就学到最好。至于你怎么学,中间有什么困难,你妈妈不关心。那么你的学习,对你妈妈来讲,就是原子的。那么你学习过程中,很容易受别人干扰,此时,就需要将你的学习隔离开,保证你的学习环境是健康的。
数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性。
数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别。
二、隔离性的体现
讲个小故事,如果同一时间有一个 update 操作和一个 select 操作,那么哪一个先执行呢?如果是 update 先执行,那么 select 拿到的就是最新的数据,而如果是 select 先执行,那么拿到的是老的数据。大多数人肯定会觉得肯定要让 update 先执行而看到新数据,但实际上这种想法是不太合理的。
比方拿时间线来说,我们的父母出生得比我们早,那么直到他们生下我的这段时间里,我是看不到这个世界的,我只看得到自己出生之后所在时间线的世界,而以前已经过世的亲人也看不到我现在所看到的世界……这就说明了我们站在上帝视角,每一个人都只能看到自己活着时候世界所对应的样子,所以我们时间线一直在延展的时候,每个人看到的世界都应该是不一样的,这才符合自然规律,人与人之间具有隔离性,因此让每一个事务都看到最新的数据是不合理的,而是应该让每一个事务在他到来时看到他应该看到的数据。这就是隔离性的体现。(所以 update 和 select 谁先跑取决于谁先来)
可是先到来的并不一定先退出,所以即使我先到来了但是操作时间很长,你在我操作结束之前也是看不到我更新后的数据的,这也是隔离性的体现。举个例子,你的朋友要转账 100 给你,在你朋友给你转钱的时候,你一定是得等他转钱事务都完成了才能查到。这是正常的隔离性。但是隔离性具体要隔离到什么程度,我们就有了隔离级别的概念!(比方说我们去服装店,如果是换裤子,我们会进试衣间,如果是换上衣,我们会根据情况,如果是换鞋子,那直接在外面换就可以了,所以这就是因为影响不同而导致隔离级别的不同)

三、隔离级别(读写并发)
-
读未提交【Read Uncommitted】:在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多并发问题,如脏读,幻读,不可重复读等,我们上面为了做实验方便,用的就是这个隔离性。
-
读提交【Read Committed】:该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。(就是你提交了我还没退出就能看到)这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select,可能得到不同的结果。
-
可重复读【Repeatable Read】:这是 MySQL 默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。(就是你提交了,并且我结束了,才能看到 ) 但是会有幻读问题。
-
串行化【Serializable】:这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了幻读的问题。(就是你结束了我才能执行,保证数据绝对安全)它在每个读的数据行上面加上共享锁。但是可能会导致超时和锁竞争(这种隔离级别太极端,实际生产基本不使用)
隔离级别如何实现:隔离,基本都是通过锁实现的,不同的隔离级别,锁的使用是不同的。常见有,表锁,行锁,读锁,写锁,间隙锁 (GAP),Next-Key 锁 (GAP+ 行锁) 等。不过,我们目前现有这个认识就行,先关注上层使用。
上面四种隔离级别关注的场景都是当有一个人在进行写的时候另一个人来读(读写并发)
四、查看与设置隔离性
-- 查看
mysql> SELECT @@global.tx_isolation; -- 查看全局隔级别
@.tx_isolation
REPEATABLEREAD
, warning ( sec)
mysql @.tx_isolation;
@.tx_isolation
REPEATABLEREAD
, warning ( sec)
mysql @;
@
REPEATABLEREAD
, warning ( sec)
[SESSION ] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED READ COMMITTED REPEATABLE READ SERIALIZABLE}
mysql session transaction isolation level serializable;
Query OK, affected ( sec)
mysql @.tx_isolation;
@.tx_isolation
REPEATABLEREAD
, warning ( sec)
mysql @.tx_isolation;
@.tx_isolation
SERIALIZABLE
, warning ( sec)
mysql @;
@
SERIALIZABLE
, warning ( sec)
mysql transaction isolation level READ UNCOMMITTED;
Query OK, affected ( sec)
mysql @.tx_isolation;
@.tx_isolation
READUNCOMMITTED
, warning ( sec)
mysql @.tx_isolation;
@.tx_isolation
READUNCOMMITTED
, warning ( sec)
mysql @;
@
READUNCOMMITTED
, warning ( sec)





