===========================================html
原文连接: 通俗理解数据库隔离机制 转载请注明出处!数据库
===========================================缓存
在理解数据库隔离机制的时候发现网上不少文章都是千篇一概,解释语言太过于标准书面化,描述的晦涩难懂,因果关系模糊。在这里将本身对隔离机制的理解描述一下,力争作到可以经过浅显的语言描述出来。
安全
数据库隔离机制是对于多线程同时操做数据库而言的。对于单线程操做数据库不存在所谓的隔离,也不须要进行隔离。这里须要注意一点【操做数据库】这里要注意区分这个操做是读取或者修改已存在的数据,仍是插入删除新的数据。多线程
数据库隔离机制四种:post
一、未提交读(Read Uncommitted)url
自定义名称:修改级别隔离(只要修改了数据,则其余事务就能够看到)
spa
能够理解为:A事务只要修改了数据,不管有没有提交,其余事务都可以读取到A事务修改后的结果。
线程
潜在问题【对于同一记录进行修改操做】:A事务修改以后未提交,B事务读取到修改以后的数据,而后在这个基础上进行操做修改并提交。而后A提交失败,数据回滚,则数据就出现异常。这就是所谓的脏读。htm
解决方案:A事务提交以后B事务才能读取到A修改以后的数据,不让读取修改但未提交的数据
二、提交读(Read Committed)
自定义名称:提交级别隔离(只有成功提交事务,则其余事务才可以看到)
能够理解为:A事务成功commit以后,其余事务才可以读取到A提交事务以后的最新数据,不然只能读取到A提交以前的原始数据。这样就解决了脏读问题。
潜在问题【对于同一记录进行修改操做】:A事务开启第一次读取数据,而后B事务开启对数据进行了修改并提交成功, 此时A事务尚未结束,又进行了一次读操做,而后便发现A事务中的两次读取的数据不一致。这就是所谓的不可重复读。同一个事务中两次读取的数据不同。【这里有一个问题我也没搞明白,为何在同一个事务中我要对同一条记录读取两次或者屡次呢?我读一次存储在缓存中不就能够了?什么状况下会发生须要读两次的的状况?应用场景有哪些?有理解的朋友还望告知!】
解决方案:在一个事务对该行数据进行操做的时候,其余事务不容许进行修改。能够理解为添加一个行级别的锁
三、可重复读(Repeatable Read)
自定义名称:事务级别隔离(A事务中的数据不会受B事务中的修改操做影响,即便B事务提交以后,A事务再次查询的数据也不会发生变化)
能够理解为:在本身的事务中复制了一套相关的数据,该数据是私有的不受其余事务的影响。所以能够解决不可重复读的问题。这里虽然解决了不可重读的问题,可是却没有解决数据覆盖的问题,也就是B操做的数据是最原始的数据(和A未修改以前的数据同样),而并非最新(A修改以后的数据)的数据。对于此隔离机制没法解决这个问题,须要使用行级锁来进行处理。
潜在问题【对于同表进行插入或删除操做】:A事务插入/删除了一条记录,可是B事务中却查询不到插入的新记录/依旧能查到删除的记录。这就是所谓的幻读。幻读是对于记录条数而言的,不是针对于某一条记录的数据而言的。这里须要注意!
解决方案:在有事务对该表进行操做的时候,不容许其余事务操做该表。添加表级锁。
四、串行读(Serializable)
自定义名称:表级别隔离(不容许同时有多个事务操做该表)
能够理解为:全部的事务串行操做该数据表。这样就能够解决幻读操做。
潜在问题:数据安全了 可是操做效率下降了。
解决方案:…………
四种隔离机制就是这样子,潜在的问题分别为:脏读,不可重复读,幻读和效率低下。脏读、幻读和效率低下的问题都可以很好的理解,但是不可重复读为何也是个须要避免的问题呢?为何在同一个事务中须要两个读取同一条数据呢?这个不太明白……
理解的时候不要看所谓的“读未提交”、“提交读”、“可重复读”和“串行读”,这只是描述了一种读取方式,并不算是一种隔离机制(我的理解)。
------end