• 事务及事务隔离级别


    一、 事务及事务隔离级别

    以下内容围绕:

    • 事务是什么?
    • 事务得ACID特性?
    • 并发事务会带来什么样的问题?

    事务是什么?
    事务是作为单个逻辑工作单元执行得一系列操作,也就是“要么全部执行,要么全部不执行”。
    假如 A 要去银行取款 100 元,这次的取款过程会涉及两个操作:

    • 将 A 的余额减少 100 元
    • A 获得 100 元取款
      这两个操作就是一次事务,因为这两个操作只能全部成功或全部失败,任何一个部分成功或失败,将会是非常严重的系统漏洞。事务的目标是保证数据库的完整性,避免各种原因引起的数据库内容不一致的问题。所以,事务可以保证数据安全,事务控制实际上就是在控制数据的安全访问

    事务的 ACID 特性
    事务必须要有四个属性:

    • 原子性(Atomicity):即不能再更细的分割了。事务操作必须是原子的,对于一个事务中的所有操作,要么全部执行(COMMIT),要么全部不执行(ROLLBACK)。

    • 一致性(Consistency):一致性指的是数据的完整性,即执行事务的前后,数据整体应该是一致的。事务必须能够让数据库从一个一致性状态变换到另一个一致性状态。对于取款的案例来说,A 的数据总值就是一致的。

    • 隔离性(Isolation):它指的是一个事务的执行不能被其他事务所干扰,这里又涉及到并发的概念。一个事务内部的操作对其他并发的事务是隔离的,简单的说,每个事务都认为是自己独占数据库。

    • 持久性(Durability):一个事务一旦提交(COMMIT),它对数据库中数据的改变就是永久性的。任何操作甚至是系统故障都不应该对其产生影响

    InnoDB 存储引擎默认的事务隔离级别是可重复读,它不能满足隔离性要求

    并发事务会带来什么样的问题

    多线程程序中,如果在并发运行的过程中对相同的数据进行了修改,就可能会引起一些问题,总结下来,可能出现的问题一共有三种:脏读、不可重复读、幻读。

    • 脏读:事务A读取了事务B当前更新的数据,但是事务B出现了回滚或未提交,事务A读到的数据就被成为“脏数据”

    • 不可重复读:事务A在执行过程中多次读取同一个数据,但是事务B在事务A的读取过程中对数据做了多次修改并提交,则会导致事务A多次读取的数据不一致,进而无法做出数据准确性判断。

    • 幻读:事务 A 在执行过程中读取了一些数据,但是事务 B 随即插入/删除数据了一些数据,那么,事务 A 重新读取时,发现多了一些原本不存在的数据/少了一些数据,就像是幻觉一样,称之为幻读

    不可重复读与幻读从概念上来说,是非常相似的。区分它们只要记住:不可重复读指的是对原来存在的数据做修改,而幻读指的是新增或者删除数据。

    二、 解读事务隔离级别

    SQL 标准定义了四种隔离级别,由低到高依次为:

    • READ-UNCOMMITTED(未提交读):它是最低的隔离级别,正如它的名称一样,它允许一个事务读取其他事务未提交的数据。这个隔离级别很少在工业环境中应用,因为它的性能并不会比其他高级别的性能好很多

    • READ-COMMITTED(提交读):它可以保证一个事务修改的数据提交之后才能被其他的事务读取。这个隔离级别是大多数数据库系统的默认隔离级别,但并不是 MySQL 默认的

    • REPEATABLE-READ(可重复读):它的核心在于 “可重复”,即在一个事务内,对同一字段的多次读取结果都是相同的,也是 MySQL 的默认事务隔离级别

    • SERIALIZABLE(串行化):是最高的隔离级别,花费的代价也是最高的,事务的处理是顺序执行的。在这个级别上,可能会导致大量的锁超时现象和锁竞争。同样,在工业级环境中,很少被使用

    它们可以逐个解决脏读、不可重复读、幻读这几类问题,除 SERIALIZABLE 之外的另外三种都不能解决所有的问题。所以,在实际的应用中,一定是有所取舍的。

    隔离界别解决的问题:

    隔离级别 脏读 不可重复读 幻读
    READ-UNCOMMITTED No No No
    READ-COMMITTED Yes No No
    REPEATABLE-READ Yes Yes No
    SERIALIZABLE Yes Yes Yes

    具体选择哪一种隔离级别应该是多个维度的考虑,例如:事务请求锁的多少(性能问题)、能够解决什么问题、业务特点等等。一般情况下,使用 InnoDB 存储引擎,我们会选择 READ-COMMITTED。

  • 相关阅读:
    一个Web文件上传的C#源代码
    DataSets and Serialization 数据集和序列化 (英文版)
    如何在Unity中播放影片
    靠边伸缩菜单的做法(类似QQ,碰到就会伸出来)
    Lightmapper
    Unity官方教學專案 Character Customization (紙娃娃系統)
    unity3d用鼠标拖动物体的一段代码
    [unity3d程序] 颜色渐变效果
    C# typeof()实例详解
    XNA Billboard(公告板技术)
  • 原文地址:https://www.cnblogs.com/liflower/p/16133333.html
Copyright © 2020-2023  润新知