数据库事务隔离级别

数据库的事务对数据并行访问的时候,有可能会出现一些问题,所以数据库设置了四个不一样的隔离级别来解决问题。数据库

在 MySQL 数据库的隔离级别能够分为四层,分别是读未提交、读提交、可重复读和串行化。与之对应出现的问题有脏读、幻读、不可重复读。性能

隔离级别

读未提交(read uncommited)

一个事务还未提交时,它作的变动就能被其余的事务看到。学习

读提交(read commited)

一个事务提交以后,它作的变动才会被其余事务看到事务

可重复读(repeatable read)

一个事务执行过程当中看到的数据,老是跟这个事务启动时看到的数据是一致的。在此隔离级别下,未提交的事务对其余事务也是不可见的。it

串行化(serializable)

对同一行记录,“写” 会加 “写锁”,“读” 会加 “读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。
此隔离级别保证了数据的正确性,可是频繁的加锁会对性能形成严重的影响。table

不一样的事务隔离级别对应的问题

脏读

在 “读未提交” 级别下,未提交的变动被其余事务看到了,对其余事务来讲,这些未提交的变动就是脏数据,这样的现象就称之为“脏读”。后台

不可重复读

在 “读提交” 级别下,只有事务提交以后,别的事务才能看到事务作的更改,可是当一个事务 A 在执行过程当中屡次查询某个值,第一次查询的时候值为 v1, 而后在事务 B 把值修改了,当事务 A 再次查询的时候,就会发现这个值不同了,明明是同一个事务进行的查询操做,两次查询出来的结果却不一样,这就是“不可重复读”并行

幻读

“幻读” 与 “不可重复读” 比较相似,事务 A 查询某个值,若是不存在,就插入,当事务 A 查询到不存在以后,事务 B 插入了这个值,事务 A 再去插入的时候就会发现以前查询不存在的值竟然有了。解决幻读的方法就是设置事务隔离级别为“串行化”,即不管读写,都对数据加锁。方法

用下面这个过程来展现一下区别数据

事务A 事务B
启动事务A,
查询获得值1
启动事务B
查询获得值1
将1改成2
查询获得值 v1
提交事务B
查询获得值 v2
提交事务 A
查询获得值 v3
  • 若隔离级别是“读未提交”,则 v1 的值就是2.这时候事务 B 虽然尚未提交,可是结果已经被 A 看到了。所以, v二、v3 都是 2。
  • 若隔离级别是“读提交”,则 v1 是 1, v2 的值是 2.事务 B 的更新在提交后才能被 A 看到。因此, v3 的值也是 2.
  • 若隔离级别是“可重复读”,则 v一、v2 是 1,v3 是 2。在“可重复读”级别下须要遵循这个要求:事务在执行期间看到的数据先后必须都是一直的。
  • 若隔离级别是“串行化”,则在事务 B 执行“将1改成2”的时候,会被锁住。知道事务 A 提交以后,事务 B 才能够继续执行。因此从 A 的角度看,v一、v2的值是 1,v3 的值是 2.

在事务的隔离级别实现上,数据库里面会建立一个视图,访问的时候以视图的逻辑结果为准。

  • 在“可重复读”隔离级别下,这个视图是在事务启动时建立的,整个事务执行期间都使用这个视图;
  • 在“读提交”级别下,这个视图是在每一个 SQL 语句开始执行的时候建立的;
  • 若是是“读未提交”级别,直接返回记录上的最新值,没有视图概念;而在“串行化”级别下直接用加锁的方式来避免并行访问。

公众号:没有梦想的阿巧 后台回复 "群聊",一块儿学习,一块儿进步