首页 > 代码库 > 数据库的隔离级别

数据库的隔离级别

一、数据库是什么?

  数据库(Database)是按照数据结构来组织、存储和管理数据的建立在计算机存储设备上的仓库。

二、为什么会需要隔离机制?

        通过数据库定义的理解,换句话说就是,数据是以一种文件的形式存储在物理结构上的。

        而对于文件的操作就是IO流的操作,即读与写的操作。

        而对于我们平常的数据操作,不管多么复杂的业务,都是select和insert/update/delete。

        我们再试想一下,如果在多线程高并发下读写操作又会出现什么情况?

        如果不做任何的处理,是不是就会出现数据处理错误。也是我们所说的,脏读或幻读。

        对于这种情况,JAVA中通常的做法就是加锁。对应于数据库就是排它锁、共享锁等。

    那加锁又是怎么处理的呢?

         加锁首先应该明确是的,什么时候加锁?对什么加锁?

         当多个线程都操作同一数据的时候,我们是不是就应该加锁。

        而数据库的隔离机制也就是数据操作的锁机制。当然数据库的机制远比这个要复杂,只是想让大家明白,一切的             重心都是数据,不要被各种术语而弄懵逼了。


三、数据库共有四种隔离级别:

  1. Read Uncommitted(读取未提交内容)

  2. Read Committed(读取提交内容)

  3. Repeatable Read(可重读)

  4. Serializable(可串行化)

四种隔离级别详解:

 1、Read Uncommitted(读取未提交内容)

    在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

    2、Read Committed(读取提交内容)

        这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

   3、Repeatable Read(可重读)

        这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。


   4、Serializable(可串行化)

         这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

         一旦读取数据,则就对事张表加锁。只允许其他事务读取数据,不能进行修改和新增数据操作。必须等待当前事务结束。


四、事务的4大特性

    4.1、原子性(Atomicity):事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行。 
    4.2、一致性(Consistemcy):事务前后,数据库的状态都满足所有的完整性约束。 
    4.3、隔离性(Isolation):并发执行的N个事务是隔离的,一个不影响一个,一个事务在没有commit之前,被修改的数据不可能被其他事务看到(通过设置数据库的隔离级别)。 
    4.4、持久性(Durability):持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。持久性主要在于DBMS的恢复性能。


五、脏读、不可重复读、幻读

     5.1 脏读、不可重复读、幻读都是对数据操作时的体现。

     5.2 脏读、不可重复读、幻读都是事务有关,也就是在并发执行时发生的情况。

     5.3 脏读:         

           脏读又称无效数据读出。一个事务读取另外一个事务还没有提交的数据叫脏读。

           例如:事务T1修改了一行数据,但是还没有提交,这时候事务T2读取了被事务T1修改后的数据,之后事务T1因                        为某种原因Rollback了,那么事务T2读取的数据就是脏的。

          解决办法:把数据库的事务隔离级别调整到READ_COMMITTED

 5.4 不可重复读:         

           不可重复读是指在同一个事务内,两个相同的查询返回了不同的结果。 

           例如:事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得                         到了不同的结果。 

           解决办法:把数据库的事务隔离级别调整到REPEATABLE_READ

    5.5 幻读:

          例如:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插                       入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一                       样。这就叫幻读。

          解决办法:把数据库的事务隔离级别调整到SERIALIZABLE_READ





数据库的隔离级别