美文网首页
数据库事务隔离级别(Transaction)

数据库事务隔离级别(Transaction)

作者: Rxlywz | 来源:发表于2017-06-12 13:24 被阅读0次

    转载自:https://my.oschina.net/huangyong/blog/160012

    什么是事务

    事务通俗理解就是做一件事情要有始有终,不能半途而废。 要么做,要么不做。也就是说,事务是一个不可分割的整体。

    事务的特性(ACDI):

    • 原子性(Atomicity):事务具有原子性,就像课本中学的,原子是构成物质的最小单位,不可分割。
    • 隔离性(Isolation):保证数据库操作之间是“隔离”的(线程之间有时也要做到隔离),彼此之间没有任何干扰。
      例:当我们编写了一条 update 语句,提交到数据库的一刹那间,有可能别人也提交了一条 delete 语句到数据库中,这个时候如果操作的是同一条数据,会出现很大的问题。
    • 一致性(Consistency):执行完数据库操作后,数据不会被破坏,这个在数据领域是非常重要的特性。
      例:如果从 A 账户转账到 B 账户,不可能A 账户扣了钱,而 B 账户没有加钱吧。
    • 持久性(Durability):执行一条 insert 语句后,数据库必须要保证有一条数据永久地存放在磁盘中,这个也算事务的一条特性。

    什么是隔离级别

    当我们编写了一条 update 语句,提交到数据库的一刹那间,有可能别人也提交了一条 delete 语句到数据库中,这个时候如果操作的是同一条数据,会出现很大的问题。所以保证数据库操作之间是“隔离”的(线程之间有时也要做到隔离),彼此之间没有任何干扰。这就是隔离性

    为了做到操作之间完全没有任何干扰,于是,就有了事务隔离级别(Transaction Isolation Level)规范。
    注意:我们讨论隔离级别的场景,主要是在多个事务并发的情况下,因此,接下来的讲解都围绕事务并发。

    隔离级别共四个级别:从上往下,级别越来越高,并发性越来越差,安全性越来越高,反之则反。 **
    Read uncommitted(读未提交 )
    Read committed(读提交)
    Repeatable read(重复读)(Mysql默认隔离级别)
    Serializable(序列化:最高级别的事务隔离,花费高,性能低,一般很少用)
    **

    事务隔离不同级别下可能出现的问题.png

    这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。

    事务的四个特性之间的相互关系
    原子性是基础,隔离性是手段,持久性是目的,真正的boss是一致性。

    这四个特性当中,其实最难理解的不是一致性,而是隔离性。因为它是保证一致性的重要手段,是工具,使用它不能有半点差池,否则后果自负!怪不得数据库行业专家们都要来研究所谓的事务隔离级别了。其实,定义这四个级别就是为了解决数据在高并发下所产生的问题,那又有哪些问题呢?
    ** Dirty Read(脏读)
    Unrepeatable Read(不可重复读)
    Phantom Read(幻读)
    **

    第一条,“脏读”其实就是我们常说的垃圾数据,例:

    脏读.png

    余额应该为 1500 元才对!请看 T5 时间点,事务 A 此时查询余额为 0 元,这个数据就是脏数据,它是事务 B 造成的,明显事务没有进行隔离,渗过来了,乱套了。
    所以脏读这件事情是非常要不得的,一定要解决掉!让事务之间隔离起来才是硬道理。

    脏读:事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作。

    那第 2 条,不可重复读又怎么解释呢?还是用类似的例子来说明:

    不可重复读.png

    事务 A 其实除了查询了两次以外,其他什么事情都没有做,结果钱就从 1000 变成 0 了,这就是重复读了。可想而知,这是别人干的,不是我干的。其实这样也是合理的,毕竟事务 B 提交了事务,数据库将结果进行了持久化,所以事务 A 再次读取自然就发生了变化。
    这种现象基本上是可以理解的,但在有些变态的场景下却是不允许的。毕竟这种现象也是事务之间没有隔离所造成的,但我们对于这种问题,似乎可以忽略。
    ** 不可重复读:事务 A 读取了事务 B 已提交的更改数据。 **

    最后一条,幻读。我去!Phantom 这个单词不就是“幽灵、鬼魂”吗?刚看到这个单词时,真的把我的小弟弟都给惊呆了。怪不得这里要翻译成“幻读”了,总不能翻译成“幽灵读”、“鬼魂读”吧。其实意义就是鬼在读,不是人在读,或者说搞不清楚为什么,它就变了,很晕,真的很晕。还是用一个示例来说话吧:

    幻读.png
    银行工作人员,每次统计总存款,都看到不一样的结果。不过这也确实也挺正常的,总存款增多了,肯定是这个时候有人在存钱。但是如果银行系统真的这样设计,那算是玩完了。这同样也是事务没有隔离所造成的,但对于大多数应用系统而言,这似乎也是正常的,可以理解,也是允许的。银行里那些恶心的那些系统,要求非常严密,统计的时候,甚至会将所有的其他操作给隔离开,这种隔离级别就算非常高了(估计要到 SERIALIZABLE 级别了)。
    事务 A 读取了事务 B 已提交的新增数据。

    以上三种情况,第一种情况是肯定不能发生,后两种情况视情况而定。
    这就是为什么必须要有事务隔离级别这个东西了,它就像一面墙一样,隔离不同的事务。

    事务思维导图.png

    相关文章

      网友评论

          本文标题:数据库事务隔离级别(Transaction)

          本文链接:https://www.haomeiwen.com/subject/albxqxtx.html