美文网首页MySQL程序员数据库知识点
数据库事务隔离级别简介

数据库事务隔离级别简介

作者: Mr_Hospital | 来源:发表于2018-09-01 11:01 被阅读1次

    Proudly powered by QKQ

    对于数据库的ACID,最近又复习了一下,整理如下。

    Q: 什么是ACID?

    A: 四个单词的首字母缩写,其分别为:

    • Atomicity(原子性)
    • Consistency(一致性)
    • Isolation(隔离性)
    • Durability(持久性)

    那么缩写的这四个又是什么?来看看WIKI:

    In computer science, ACID (Atomicity, Consistency, Isolation, Durability) is a set of properties of database transactions intended to guarantee validity even in the event of errors, power failures, etc.

    翻译一下:
    在计算机科学中,ACID是数据库事务(Database transactions)的一组属性,用来保证数据库在出错、断电等情况下的正确性(Validity)。
    换句话说,数据库中的事务,如果满足了ACID,那么在出错和断电的情况下,也能保证其正确性。所谓正确,也就是在该类场景下,表现的行为符合预期。
    那么,什么样的行为才是符合预期的行为?留待后面回答。

    K: 事务的属性,正确性
    Q: 什么样的行为才是预期的行为?

    Q: 什么是事务?

    A: 依然来看看wiki:

    In the context of databases, a sequence of database operations that satisfies the ACID properties (and these can be perceived as a single logical operation on the data) is called a transaction.

    翻译:
    在数据库的上下文中,一系列满足ACID条件(并在逻辑上可以认为是对数据的一个操作)的操作,称为事务。
    主谓拆分:

    • 事务,是一系列的操作
    • 这一系列的操作,满足ACID
    • 逻辑上,这一系列的操作可以看做是对数据的一个操作

    举个例子:
    转账:从李四的账户转200块到张三的的账户上。

    • 一系列的操作:
      • 从李四账户上减去200块
      • 在张三账户上加上200块
    • 这一系列的操作符合ACID
    • 逻辑上讲,转账可以看做对数据的一个操作

    K: 系列操作,满足ACID,逻辑单个
    R: 组合起来,形成事务,all的关系
    Q: ACID分别是什么?什么情况才算满足了?

    Q: Atomicity是什么?

    A: 继续WIKI

    An atomic transaction is an indivisible and irreducible series of database operations such that either all occur, or nothing occurs.

    翻译:
    一个原子事务是指一系列不可分割、不可消减的操作,它们要么全执行,要么全不执行。

    首先Atomicity是事务的一个属性,所以解释的时候,必然会涉及到事务。解释具体这个属性的事务的预期行为
    这里,有一个我认为十分好记的关键字:All or Nothing,我翻译为所有或无。
    K: 事务的属性,All or Nothing

    Q: Consistency是什么?

    A: WIKI

    Consistency in database systems refers to the requirement that any given database transaction must change affected data only in allowed ways.

    翻译:
    数据库中的一致性,要求数据库事务对数据的影响必须是被允许的。

    被谁允许的呢?
    数据库本身。数据库具有一些constraints(限制),满足这些限制条件的,即是被允许的,否则就是不被允许的。即不允许,也就是不满足数据库的限制条件。

    什么是数据库的限制(Database Constraints)?

    A constraint is a property assigned to a column or the set of columns in a table that prevents certain types of inconsistent data values from being placed in the column(s).
    -- What is data integrity? Explain constraints

    翻译:
    一个限制,是应用于数据库表中的一个或者几个列的规则,这些规则防止(与其他列不一样的)不一致的数据被存放到列中。

    主谓分析:

    • 限制是规则
    • 针对表中的列的规则
    • 防止不一致的数据出现

    数据库的限制(Database Constraints)有哪些?

    • Entity Integrity,保证没有重复的列
    • Domain Integrity ,数据满足定义的格式、类型、范围等
    • Referential integrity ,存在引用的列不能被删除
    • User-Defined Integrity ,用户自定义的,不在上面三个里面的规则

    举些例子:

    • Primary Key (主键)
    • Foreign Key (外键)
    • Not Null
    • Unique
    • ...

    Consistency,一致性,我认为就是需要数据库里面的数据在时间上是一致的,比如1分钟前插入的数据和1分钟之后插入的数据都是满足同一套约束条件的。
    所谓一致,即满足同一套规则。

    K: 一致,约束,同一套规则

    Q: Isolation是什么?

    A: WIKI

    Isolation is typically defined at database level as a property that defines how/when the changes made by one operation become visible to other.

    翻译:
    隔离性,是指数据库里面的一个操作产生的影响如何/什么时候对另一个操作可见。
    这里有些断章取义的意味,更合适的,我认为应该是:
    隔离性,规定了什么时候,一个事务产生的影响如何对另一个事务可见。

    Isolation牵涉到两个概念:

    • Concurrency Control。并发控制,往往通过加锁的方式对并发操作进行一定的控制
    • Isolation Levels。隔离级别,由高到低分为四种:
      • Serializable, 串行,即两个事务不能同时执行,只有一个执行完成之后,才执行另一个
      • Repeatable reads, 可重复读
      • Read committed, 提交读,简单来说,就是提交了的数据才能读到
      • Read uncommitted, 未提交读,即未提交的数据也能读到

    committed的意思就是提交,一般表示一个事务的结束。

    Read Uncommitted: 直接翻译一下就是读取了未提交的数据,即事务A在进行操作的时候,事务B对数据产生的改动会被A直接读取到。这样的影响在于:事务A读取到的事务B产生的改动是不安全的,因为该改动可能被事务B回滚。这种情况,称为“脏读”,即读取了脏数据(事务B产生的改动)。

    Read Committed: 直译就是读取的是已提交的数据。显而易见,这可以避免上面提到的脏读。然而,这样也有问题。其场景为:事务A在一个事务中需要两次读取同一条数据,在读取的间隙,事务B对该数据进行了改动,然后提交了。此时会造成事务A
    两次读取到的数据不一样,虽然按道理应该是一样的。这样的问题,称为“不可重复读”

    Repeatable Reads: 直译为可重复读。即保证了同一事务中两次读取的数据是一致的。即在事务开始之后,其他事务对数据的改动对该事务不可见。这时候出现的问题是,如果事务A中两次进行了范围查询(比如select * from user where age > 10),在两次查询之间,事务B插入了一条满足查询的数据,那么事务A中两次范围查询的结果不一样。此时事务A感觉出现了幻觉,这种情况,我们称为幻读。

    Serializable:事务串行执行,可以解决上面提到的“脏读”、“不可重复读”、“幻读”问题,然而代价是不支持并行,性能差。

    鉴于比较繁琐,列个表:

    事务级别 可能出现的问题 出现问题的场景 造成的影响
    Read Uncommitted 脏读 事务A读取了事务B即将回滚的数据 读取了错误的数据
    Read Committed 不可重复读 事务A进行了两次数据读取,读取间隙,该数据被事务B改动且提交了 两次读取内容不一样,可能造成操作出错
    Repeatable Reads 幻读 事务A进行了两次范围读取,读取间隙,该范围被事务B插入了数据且提交了 两次读取内容不一样,可能造成操作出错
    Serializable 串行执行 性能低

    K: 多个事务,影响可见,隔离级别
    R:
    Q: 各个事务级别如何实现?

    Q: 各个事务级别如何实现?

    A: 大约有两种方式:

    • 多版本并发控制(MVCC,Multi-Version Concurrency Control)

    先来看看锁的实现方式。这里我们使用Mysql的一些定义[6],锁可以分为两种:

    • 共享锁(shared(s) lock),多个事务可以共享
    • 排他锁(exclusive(x) lock),同一时间,只能一个事务可以持有

    一般来说:

    • 读取数据的时候,需要获取共享锁,即s锁
    • 修改或者删除数据的时候,需要获取排他锁

    此处考虑两种情况及其处理方式:

    • 假设事务T1持有对行r的一个s锁,此时另一个事务T2需要对r行进行操作:
      • 事务T2希望获取s锁,此时可以立即获取到s锁
      • 事务T2希望获取x锁,此时无法立即获取到(需要等待之前的s锁被释放。有没有可能多个事务一直对某行加s锁,而一个想获取到x锁的事务一直都无法得到x锁(starving problem)?此时可以考虑请求锁的顺序,比如将锁的请求放到一个队列里面,先进先出。)
    • 假设事务T1持有对行r的一个x锁,此时另一个事务T2需要对r行进行操作:
      • 事务T2希望获取s锁,无法立即获取,需要等待x锁释放
      • 事务T2希望获取x锁,无法立即获取,需要等待x锁释放

    可能的实现方式(读写前获取锁,事务结束之后释放锁):

    隔离级别 读写锁实现
    Read Uncommitted 无需任何锁
    Read Committed 写锁等待读锁全部被释放,表明所有读操作完成。
    写锁排斥读锁,因此写入的时候没有任何读操作
    Repeatable Read 同上,由于写入的同时保证了没有事务在进行读取,因此不会出现不可重复读
    Serializable 全都用排他锁咯

    MVCC可以归纳为snapshot(快照)的其中一种。
    为什么要使用MVCC?

    最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅度提高了InnoDB的并发度。
    ---------http://mysql.taobao.org/monthly/2017/12/01/

    隔离级别 读写锁实现
    Read Uncommitted 不支持
    Read Committed 读取之前获取快照,写锁并不需要等待读锁,读锁也不需要等待写锁的释放
    事务读取的是快照,因此不会读取到事务未提交的数据
    Repeatable Read 事务一开始的时候就获取快照
    Serializable 不支持

    Q: Durability是什么?

    A: WIKI

    In database systems, durability is the ACID property which guarantees that transactions that have committed will survive permanently.

    翻译:
    数据库中,持久性,表示事务提交之后,其产生的改变将会永久(permanently)存在。

    就是说,事务提交了,那么这个事务的操作,对数据也就生效了。就算之后数据库挂了,机器断电了,这个改动依然存在,重启之后依然存在。
    顺便提一句,对断电之后的处理,有一种方式是:事务提交之前,先把改动记录到log里面,然后每次启动的时候从log里面恢复数据。
    K: 事务提交之后,依然存在
    R: 发生的时间,结果

    参考资料:
    [1], https://en.wikipedia.org/wiki/Isolation_%28database_systems%29
    [2], https://docs.microsoft.com/en-us/sql/connect/jdbc/understanding-isolation-levels?view=sql-server-2017
    [3],[https://www.ibm.com/support/knowledgecenter/en/SSEPGG_10.5.0/com.ibm.db2.luw.admin.perf.doc/doc/c0004121.html(https://www.ibm.com/support/knowledgecenter/en/SSEPGG_10.5.0/com.ibm.db2.luw.admin.perf.doc/doc/c0004121.html)
    [4], http://highscalability.com/blog/2011/2/10/database-isolation-levels-and-their-effects-on-performance-a.html
    [5], https://www.allinterview.com/showanswers/5542/what-is-data-integrity-explain-constraints.html
    [6], https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html
    [7], 高性能Mysql
    [8], http://ithare.com/databases-101-acid-mvcc-vs-locks-transaction-isolation-levels-and-concurrency/

    相关文章

      网友评论

        本文标题:数据库事务隔离级别简介

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