Mysql——事务隔离
内容出自丁奇45讲
提到事物肯定就要提到ACID
A:Atomicity 原子性
C:Consistency 一致性
I:IsoLation 隔离性
D:Durability 持久性
当数据库有多个数据执行的时候,就可能会出现脏读,不可重复读,幻读的问题为了解决这样的问题,就有了“隔离级别”的概念
脏读:在执行事务A的时候,读取到了事务B未提交的数据,之后事务B发生了回滚,事务A读到了脏的数据
不可重复读:在同一个事务中读同一个字段,内容一不一样,比如说事务A内执行Select age from A,第一次执行获得的年龄是18,然后事务B对年龄进行了更改将年龄改成了20,再后面事务A再执行Select age from A的语句,读到的年龄不为18,而是20,前后多次读取,数据内容不一致
幻读:在同一个事务中读一个表某个数据的行总量,两次读取的行数不一样,比如说事务A执行Select count() from A,第一次读到的行数是100行,然后其他事务对这个表进行了修改,行数发生了变化,之后事务A再执行Select count() from A,前后多次读取,表的行数不一致
不理解的同学们可以再看一看这个博主的文章,十分的详细https://blog.youkuaiyun.com/qq_33591903/article/details/81672260
在谈隔离级别之前,你首先要知道,你隔离得越严实,效率就会越低。因此很多时候,我们都要在二者之间寻找一个平衡点。SQL标准的事务隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(serializable )。下面我逐一为你解释:
- 读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。
- 读提交是指,一个事务提交之后,它做的变更才会被其他事务看到。
- 可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
- 串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。
其中“读提交”和“可重复读”比较难理解,所以我用一个例子说明这几种隔离级别。假设数据表T中只有一列,其中一行的值为1,下面是按照时间顺序执行两个事务的行为。
mysql> create table T(c int) engine=InnoDB;
insert into T(c) values(1);
我们来看看在不同的隔离级别下,事务A会有哪些不同的返回结果,也就是图里面V1、V2、V3的返回值分别是什么。
- 若隔离级别是“读未提交”, 则V1的值就是2。这时候事务B虽然还没有提交,但是结果已经被A看到了。因此,V2、V3也都是2。
- 若隔离级别是“读提交”,则V1是1,V2的值是2。事务B的更新在提交后才能被A看到。所以, V3的值也是2。
- 若隔离级别是“可重复读”,则V1、V2是1,V3是2。之所以V2还是1,遵循的就是这个要求:事务在执行期间看到的数据前后必须是一致的。
- 若隔离级别是“串行化”,则在事务B执行“将1改成2”的时候,会被锁住。直到事务A提交后,事务B才可以继续执行。所以从A的角度看, V1、V2值是1,V3的值是2。
事务B才可以继续执行。所以从A的角度看, V1、V2值是1,V3的值是2。
在实现上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。在“读提交”隔离级别下,这个视图是在每个SQL语句开始执行的时候创建的。这里需要注意的是,“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;而“串行化”隔离级别下直接用加锁的方式来避免并行访问。
本内容用于自身学习,内容出自丁奇45讲