暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL的隔离性隔的是什么?

程序猿读历史 2021-05-31
387

前言

    根据我的计划,接下去文章要涉及到MySQL最关键、最复杂、最牛逼的两个特性:MVCC( Multiversion concurrency control,多版本并发控制)、锁。MySQL为什么要有MVCC和锁?是为了具备事务的能力。那什么是数据库的事务呢?事务是关系型数据库的重要特性,最经典例子是银行转账:A往B转账10元,第一步A账户减10元,第二步B账户加10元。转账的整个过程就是一个事务,事务内的操作要么全部成功,要么全部失败。如果只成功了一部分(A账户扣款成功,B账户加上失败),必须得回滚(A账户的扣款必须回滚)。简单说,数据库的事务就是完整、不可分离的一套写动作。

    事务具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)四个特性,简称 ACID,缺一不可。MySQL事务的四个特性中ACD三个特性是通过Redo Log(重做日志)和Undo Log (回滚日志)实现的,而隔离性是通过MVCC和锁来实现。所以在介绍MVCC、lock之前,得先了解什么是隔离性,本文将详细介绍MySQL的隔离机制。

    另外,目前我们所说的MySQL一般都是默认指InnoDB存储引擎,因为常见的引擎中只有InnoDB支持事务,且只有InnoDB通过索引支持行级锁

问题

在数据库高并发情况下,不同事物之间的相互读写会产生下列三个问题:

假设有一个表T,只有一列C,该表只有一行数据,值为2.

  • 脏读

脏读就是指当A事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,此时B事务也访问这个数据,然后使用了这个数据。主要针对update
操作。

  • 不可重复读

是指一个事务中多次读同一数据结果不一致。在A事务还没有结束时,B事务也访问该数据。此时在A事务中的两次读数据之间,由于B事务的修改提交,那么A事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。主要针对update
操作。

  • 幻读

幻读并不是说两次读取获取的结果集不同,幻读是某一次的查询操作得到的结果无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。主要针对insert
操作。

注意:不可重复读的和幻读很容易混淆。不可重复读侧重表达读-读,即两次读的数据不一致。而幻读则是说读-写,强调的是读到之前没有出现过的数据,用写来证实读的是鬼影。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

定义

隔离性是指事务内部的操作与其他事务是隔离的,并发执行的各个事务之间读写不能互相干扰。简单起见,我们仅考虑最简单的读操作和写操作(暂时不考虑带锁读等特殊操作),那么隔离性的探讨,主要可以分为两个方面:

  • (一个事务)写操作对(另一个事务)写操作的影响:锁机制保证隔离性。

  • (一个事务)写操作对(另一个事务)读操作的影响:MVCC保证隔离性。

为了解决脏读、不可重复读和幻读问题,MySQL通过事务隔离机制实现。有以下四种隔离机制:

  • READ-UNCOMMITTED(读未提交)

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。读取未提交的数据,也被称之为脏读。

  • READ-COMMITTED(读已提交)

事务提交后,做得变更才能被其他事务看到。这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。解决了脏读。

  • REPEATABLE-READ(可重复读)

一个事务执行过程中看到的数据,总是跟跟这个事务启动的时候看到的数据时是一致的。未提交变更,在其他事务是不可见的。解决了不可重复读。

注意:RR是官方MySQl的默认隔离级别,阿里云RDS的隔离级别默认是RC

  • SERIALIZABLE(串行化)

对于同一行记录,写和读都会加锁,当出现读写锁冲突的时候,后访问的。解决了幻读。    以上四种是MySQL的隔离制度,四种隔离级别是逐级严格,事务级别越严格,并发性越差,隔离性越好。我们往往需要在隔离性和并发性做一个平衡。

    另外,事务隔离级别支持会话级、全局级动态修改(重启后失效),也可以在配置文件中加入(需要重启生效),但是修改时要注意大写,否则会失败。

    会话动态修改示例(右划观看效果更佳)

    mysql>set transaction_isolation='REPEATABLE-READ';
    Query OK, 0 rows affected (0.00 sec)
    mysql>
    mysql>show variables like '%transaction_isolation%';
    +-----------------------+-----------------+
    | Variable_name | Value |
    +-----------------------+-----------------+
    | transaction_isolation | REPEATABLE-READ |
    +-----------------------+-----------------+
    1 row in set (0.00 sec)



    附录

    MySQL各个引擎属性(右划观看效果更佳)

      mysql>select * from information_schema.`ENGINES`\G;
      *************************** 1. row ***************************
      ENGINE: CSV
      SUPPORT: YES
      COMMENT: CSV storage engine
      TRANSACTIONS: NO
      XA: NO
      SAVEPOINTS: NO
      *************************** 2. row ***************************
      ENGINE: MRG_MYISAM
      SUPPORT: YES
      COMMENT: Collection of identical MyISAM tables
      TRANSACTIONS: NO
      XA: NO
      SAVEPOINTS: NO
      *************************** 3. row ***************************
      ENGINE: MyISAM
      SUPPORT: YES
      COMMENT: MyISAM storage engine
      TRANSACTIONS: NO
      XA: NO
      SAVEPOINTS: NO
      *************************** 4. row ***************************
      ENGINE: BLACKHOLE
      SUPPORT: YES
      COMMENT: dev/null storage engine (anything you write to it disappears)
      TRANSACTIONS: NO
      XA: NO
      SAVEPOINTS: NO
      *************************** 5. row ***************************
      ENGINE: PERFORMANCE_SCHEMA
      SUPPORT: YES
      COMMENT: Performance Schema
      TRANSACTIONS: NO
      XA: NO
      SAVEPOINTS: NO
      *************************** 6. row ***************************
      ENGINE: MEMORY
      SUPPORT: YES
      COMMENT: Hash based, stored in memory, useful for temporary tables
      TRANSACTIONS: NO
      XA: NO
      SAVEPOINTS: NO
      *************************** 7. row ***************************
      ENGINE: ARCHIVE
      SUPPORT: YES
      COMMENT: Archive storage engine
      TRANSACTIONS: NO
      XA: NO
      SAVEPOINTS: NO
      *************************** 8. row ***************************
      ENGINE: InnoDB
      SUPPORT: DEFAULT
      COMMENT: Supports transactions, row-level locking, and foreign keys
      TRANSACTIONS: YES
      XA: YES
      SAVEPOINTS: YES
      *************************** 9. row ***************************
      ENGINE: FEDERATED
      SUPPORT: NO
      COMMENT: Federated MySQL storage engine
      TRANSACTIONS: NULL
      XA: NULL
      SAVEPOINTS: NULL
      9 rows in set (0.00 sec)


      ERROR:
      No query specified


      文章转载自程序猿读历史,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论