事务隔离性理论
- 理解隔离性 MySQL 服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务方式进行。
- 一个事务可能由多条 SQL 构成,这意味着任何一个事务都有执行前、执行中、执行后的阶段。所谓的原子性,就是让用户层要么看到执行前,要么看到执行后。执行中出现问题,可以随时回滚。所以单个事务对用户表现出来的特性就是原子性。
- 但所有事务都要有个执行过程,在多个事务各自执行多个 SQL 的时候,还是可能会出现互相影响的情况。例如:多个事务同时访问同一张表,甚至同一行数据。
- 数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性。
- 数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别。
理解隔离性
- SQL 操作都是具有原子性的,update 和 select,谁先来谁就先跑。
- 每一个人都只能看到自己活着时候世界所对应的样子,所以我们时间线一直在延展的时候,每个人看到的世界都应该是不一样的,这才符合自然规律。人与人之间具有隔离性,因此让每一个事务都看到最新的数据是不合理的,而是应该让每一个事务在他到来时看到他应该看到的数据。这就是隔离性的体现。
- 隔离性具体要隔离到什么程度,我们就有了隔离级别的概念。
- 隔离性就是你可以看到你出生后的时间线的内容,不能看到你出生前的内容。
- 隔离级别是你试衣服的时候要进试衣间,试鞋子就不用进试衣间。
隔离级别
- 读未提交:在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际公司不会用这种),这种相当于没有隔离级别。
- 读提交:一个事务 commit 之后,另一个事务可以看到这个事务的提交结果。
- 可重复读:相当于一个事务做完操作后,另一个事务也做完操作后,两个事务都关闭后,重新启动事务才能看到结果,在操作的途中是看不到结果的。类比于两个小孩在浑浊的水中潜水,一个小孩要确认另一个小孩是否还在潜水要浮上水面才能知道结果。这是 MySQL 默认的隔离级别,在操作的途中看到的结果是相同的。
- 串行化:事务最高的隔离级别,一个 mysql 执行完成后另一个 mysql 才能执行,会影响效率。
- 隔离,基本都是通过锁实现的,不同的隔离级别,锁的使用是不同的。
上面四种隔离级别关注的场景都是当有一个人在进行写的时候另一个人来读(读写并发),读读的场景都用的是串行化,一个任务进行完才能进行下一个任务。
事务隔离级别的设置和查看
- 只影响当前事务的隔离级别,mysql 会默认使用 session 的隔离级别。
- 全局的隔离级别对所有的事务都影响,全局的改了,当前会话的和另一个事务的都会改变(在重新登入后更改)。
-- 查看会话 (当前) 全局隔级别(默认用全局的初始化)
SELECT @@session.tx_isolation;
-- 设置全局隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- 查看全局隔级别
SELECT @@global.tx_isolation;
/*
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
*/
-- 查看会话 (当前) 全局隔级别(默认用全局的初始化)
SELECT @@session.tx_isolation;
/*
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ |
+------------------------+
*/
@;


