美文网首页MySQL
MySQL的事务隔离级别

MySQL的事务隔离级别

作者: 这真的是一个帅气的名字 | 来源:发表于2019-08-21 00:13 被阅读4次

什么叫事务

事务就是一组sql组成的操作单元,要么操作全部成功,要么全部失败。

事务的基本要素(ACID)(四个)

  • 原子性

一个事务必须被视为一个不可分割的最小工作单元,整个事务要么全部成功,要么失败全部回滚。事务中不能只执行其中的一部分操作。

  • 一致性

数据库总是从一个一致的状态转换到另外一个一致的状态。比如两个update,第一个update之后系统崩溃了,也不会对数据有影响,因为事务还没有提交。

  • 隔离性

一个事务所做的修改,在提交之前,对其他事务应该是不可见的。

  • 持久性

一旦事务提交,那么所做的修改就会永久的保存到数据库中。

事务的并发问题(三种)

脏读

事务B读取了事务A未提交的修改数据

不可重复读

事务A一直查询,事务B在事务A查询的期间对数据做了更新,导致事务A读取的结果不一致

幻读

事务A对摸个数据范围记录时,事务B在事务A查询的范围内插入了新的记录。当事务A再次读取事务时,会发现新增的记录,就想出现幻觉似的。

事务的隔离级别(四种)

  • 读未提交(read-uncommitted)

允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

例子:
①事务A命令行设置事务模式为read uncommitted(未提交读),查询表member的初始状态:

 set session transaction isolation level read uncommitted;
 start transaction;
 select * from member;
image.png

②事务A到此暂停,打开事务B,让事务B更新一条数据

 set session transaction isolation level read uncommitted;
 start transaction;
 update member set age = age-10 where name = 'zhangsan';
select * from member;
image.png

③虽然事务B的事务还没提交,但是事务A就可以查询到事务B已经更新的数据:


image.png

④事务B如果回滚,所有的操作都将会被撤销,那事务A查询到的数据其实就是脏数据:


image.png
⑤如果事务A执行更新语句update member set age = age -3 where name='zhangsan';,zhangsan的age没有变成0,居然是10,What???3-3=10???,这样子算其实是因为事务A不知道事务B回滚了.所以会用3-3=0.其实程序是13-3=10。要想解决这个问题可以采用读已提交的隔离级别
image.png
  • 不可重复读(read-committed)

只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

①把事务A的事务模式设置成read committed(未提交读),查询表member的所有记录:

 set session transaction isolation level read committed;
 start transaction;
image.png

②打开事务B,更新一条数据


image.png

③事务A再查询,查不到事务B的修改,解决了脏读


image.png
④事务B提交事务,事务A再查询,结果不一致,即产生了不可重复读的问题
image.png
  • 可重复读(repeatable-read)

可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

①打开事务A并设置当前事务模式为repeatable read,查询表member的所有记录

 set session transaction isolation level repeatable read;
start transaction;
select * from member;
image.png

②事务A提交之前打开事务B更新一条并且提交事务


image.png

③事务A再次查询,发现此时的信息是一致的,没有出现不可重复读的问题


image.png
④事务A更新一条数据然后查看,会发现数据跟想象的不一样,age的数据是根据事务B的结果进行计算的。数据的一致性倒是没有被破坏。可重复读的隔离级别下使用了MVCC机制,select操作不会更新版本号,是快照读(历史版本);insert、update和delete会更新版本号,是当前读(当前版本)。
image.png
⑤当事务B重新开启事务添加一条信息的话会出现事务锁,事务A还是之前数据。没有出现幻读。
image.png
image.png
  • 串行化(serializable)

完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
①打开事务A,并设置当前事务模式为serializable,查询表member的初始值:


image.png

②打开事务B,插入一条数据,会报错。mysql中事务隔离级别为serializable时会锁表,因此不会出现幻读的情况,这种隔离级别并发性极低,开发中很少会用到。


image.png

重要

①事务隔离级别为读提交时,写数据只会锁住相应的行
②事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式 是next-key锁,如果检索条件没有索引,更新数据时候会锁住整张表。一个间隙被事务加了锁,其他事物是不能再这个间隙插入记录的,这样可以防止幻读。
③事务隔离级别为串行化时,读写数据都回锁住整张表
④隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也就越大。
mysql的mvcc机制
next-key锁

级别顺序(由低到高)

Read uncommitted (读未提交)、Read committed(读提交/不可重复读) 、Repeatable read(可重复读) 、Serializable (串行化)

相关文章

  • 聊聊MySQL的隔离级别

    原文:聊聊MySQL的隔离级别 | MySQL隔离级别原理参考:oracle - mysql - 数据库事务隔离级...

  • mysql事务隔离级别的实现原理

    mysql事务隔离级别的实现原理 mysql innodb中的四种事务隔离级别[https://www.jians...

  • Mysql事务

    1) mysql事务的ACID特性 2)MySQL事务隔离级别

  • MySQL 事务隔离级别解析和实战

    MySQL 事务隔离级别解析和实战 1、MySQL 隔离界别查看 查看回话隔离级别 查看系统隔离级别 2、MySQ...

  • mysql隔离级别

    一、MySQL事务隔离级别 mysql默认的事务隔离级别为repeatable-read(可重复读) 1.未提交可...

  • Mac系统mysql设置事务隔离级别

    Mac系统mysql设置事务隔离级别 MySQL数据库事务隔离级别主要有四种: Serializable 串行化,...

  • MYSQL事务

    常用语句 MYSQL事务,锁表 事务控制语句 事务的隔离级别 隔离级别描述产生风险READUNCOMMITTED ...

  • 面试官:说一下MySQL事务隔离级别?

    MySQL 事务隔离级别是为了解决并发事务互相干扰的问题的,MySQL 事务隔离级别总共有以下 4 种: READ...

  • 数据库事务相关

    事务隔离级别(tx_isolation)mysql 有四级事务隔离级别 每个级别都有字符或数字编号 级别symbo...

  • mysql笔记

    mysql笔记 查看事务隔离级别 show variables like '%iso%'; 设置事务级别 mysq...

网友评论

    本文标题:MySQL的事务隔离级别

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