当前位置: 首页 > news >正文

猿创征文|全方位快速了解事务的4种隔离级别

MySQL事务隔离级别

  • 事务以及事务的隔离级别
    • 1. 概念
    • 2. 事务的特性
    • 3. 事务的隔离级别
      • 3.1 Q:那么为什么事务需要有隔离级别呢?
      • 3.2 Q:那么什么事务并发会产生的问题?
          • 总结:不可重复读的和幻读很容易混淆
      • 3.3 Q:事务的隔离级别分为哪几种?
      • 总结
    • 4. 举例说明隔离级别
      • 4.1 读未提交
      • 4.2 读已提交
      • 4.3 可重复读
      • 4.4 可串行化(可序列化)

事务以及事务的隔离级别

1. 概念

事务就是用户定义的一系列操作,这些操作可以视为一个完整的逻辑处理工作单元,要么全部执行,要么全部不执行,是不可分割的工作单元。

数据库事务: 通常指对数据库进行读或写的一个操作序列(如,一条sql语句就是一个事务),这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;是数据库操作的最小工作单元。

2. 事务的特性

我们都知道事务四大基本特性,那就是ACID

  • 原子性(Atomicity):事务开始后所有操作,要么都做,要么都不做

  • 一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏

    事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。

    如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态;

    比如A向B转账,不可能A扣了钱,B却没收到。

  • 隔离性(Isolation):一个事务的执行不能其它事务干扰;

    同一时间,只允许一个事务请求同一数据**,不同的事务之间彼此没有任何干扰**。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

  • 持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

    指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的

3. 事务的隔离级别

3.1 Q:那么为什么事务需要有隔离级别呢?

A:事物隔离级别,是为了解决事务并发产生的问题;事物隔离级别越高,并发下产生的问题就越少,但付出的资源消耗也越大,所以我们要根据实际使用在并发性和性能之间做一个权衡,因此有了事物隔离级别。

3.2 Q:那么什么事务并发会产生的问题?

事务的并发执行可能会产生三种常见的问题:脏读、不可重复读、幻读

  • 脏读: 事务A读取了事务B更新的数据(但此时B还未回滚【提交数据】),那么A读取到的数据是脏数据;

    eg:事务A先执行,查到age=10;接着事务B执行,将age改成11,事务B未提交;接着继续事务A进行查询,得到age=11;但此时事务B还未提交,所以这就是读未提交,也就是我们所说的脏读

  • 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。

  • 幻读: 系统管理员A学生的成绩按照等级分类,但是系统管理员B在这个时候插入了一条成绩记录,当系统管理员A修改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

总结:不可重复读的和幻读很容易混淆

不可重复读侧重于修改;
幻读侧重于新增或删除;

解决不可重复读的问题只需锁住满足条件的行( 行级锁);

解决幻读需要锁表(间隙锁防止幻读)

3.3 Q:事务的隔离级别分为哪几种?

MySql种事务的隔离级别分为四种:读未提交;读已提交;可重复读;串行化

  • 读未提交 read uncommitted :事务A会读到事务B还未提交的数据 (会出现:脏读,不可重复读,幻读)

    设置当前会话的隔离级别:set session transaction isolation level READ UNCOMMITTED;

  • 读已提交 read committed :事务A不会读到事务B还未提交的数据 (避免了脏读
    在读提交的隔离级别下,当事务B修改完数据尚未提交时,事务A是无法读取到修改的数据的;当事务B提交事务后,事务A才可以看到修改的结果

  • 可重复读 repeatable read:(MySQLd的默认隔离级别)(避免了脏读不可重复读
    可以发现,当事务B提交后,事务A查询的结果依然是事务A开启时读到的数据,这就是所谓的可重复读:

    也就是说事务开启时读到的数据,在事务提交前,是一致的,不会因为外面事务的修改提交而改变开启事务前读到的值。

  • 串行化 serializable :(避免了所有并发问题)读写数据都会锁住整张表;
    就是严格按照串行序列排队执行事务,一个事务A执行提交结束以后,事务B才会开启。

总结

隔离级别脏读不可重复读幻读
读未提交
读已提交×
可重复读××
串行化×××

4. 举例说明隔离级别

4.1 读未提交

设置A的隔离级别为read uncommitted

在这里插入图片描述
A:启动事务,A进行查询,得到初始数据;

在这里插入图片描述

B:启动事务,更新数据,但不提交;id=1,num=1改为num=10;

在这里插入图片描述

A:再次读取数据,发现读取到了B未提交的数据,这就是脏读;

在这里插入图片描述

B:回滚事务;

在这里插入图片描述

A:再次读取数据,发现数据变回初始状态;

在这里插入图片描述
总结: 先事务A,查到num=1;接着再事务B,将num改成10,接着继续事务A进行查询,得到num=10;但此时事务B还未提交,所以这既是读未提交,也就是我们所说的脏读

4.2 读已提交

设置A的隔离级别为read committed

在这里插入图片描述
A:启动事务,A进行查询,得到初始数据;

在这里插入图片描述

B:启动事务,更新数据,但不提交;id=1,num=1改为num=10;

在这里插入图片描述

A:再次读取数据,发现数据并未被修改;

在这里插入图片描述

B:提交事务;

在这里插入图片描述

A:再次读取数据,发现数据已经变化,说明提交的修改被事务中的A读到了,这就是不可重复读

在这里插入图片描述
总结:读已提交读隔解决了脏读的问题,但仍有不可重复读的问题;即事务A在两次查询的数据不一致。

4.3 可重复读

设置A的隔离级别为repeatable read

在这里插入图片描述
A:启动事务,此时数据为初始状态;

在这里插入图片描述

B:启动事务,更新数据,但不提交;

在这里插入图片描述

A:再次读取数据,发现数据未被修改;

在这里插入图片描述

B:提交事务;

在这里插入图片描述

A:再次读取数据,发现数据仍未发生变化,则说明可以重复读;

在这里插入图片描述

B:插入/更新一条新的数据记录,并提交

在这里插入图片描述

A:再次读取数据,发现数据未发生变化,虽然可以重复读了,但是却发现读的不是最新数据记录,这就是所谓的“幻读”

在这里插入图片描述

A:提交本次事务,再次读取数据,发现读取到了更新的数据

在这里插入图片描述
总结: 可重复读只允许读取已提交记录,也就是说事务开启时读到的数据,在事务提交前,是一致的,不会因为外面事务的修改提交而改变开启事务前读到的值。但是在事务A两次读取一个记录期间,事务B插入新纪录,事务A是可能在未提交之前读取不到更新的记录,这就是幻读

4.4 可串行化(可序列化)

设置A的隔离级别Serializable

在这里插入图片描述
A:启动事务,此时数据为初始状态

在这里插入图片描述
B:发现B此时进入了等待状态,原因是因为事务A尚未提交结束,只能等待;(此时,B可能会发生等待超时)

在这里插入图片描述

A:提交事务

在这里插入图片描述
B:发现插入成功

在这里插入图片描述
总结serializable完全锁定整张表,当事务B来查询同一份数据就必须等待,直到事务A完成并解除锁定为止。就是严格按照串行序列排队执行事务,事务B只有等待到事务A执行提交结束,事务B才会开启。因此性能上消耗比较大。

参考博文:https://www.jianshu.com/p/8d735db9c2c0

相关文章:

  • J9数字论:Web3.0对比传统Web2.0的区别
  • 《linux程序设计》笔记第一章
  • Java中的线程池的线程数量如何确定?
  • Jumpserver堡垒机部署(完整过程)
  • SpringBoot基于AOP实现RocketMQ发送与消费
  • 全球与中国亚麻籽行业消费量调研及未来产销需求分析报告2022-2028年
  • 链接装载与库:第八章——Linux共享库组织
  • java应用提速(速度与激情)
  • Java学习----Set接口
  • To enable Secure Boots and Flash Encryption using the ESP Flash download tool
  • FastFlow(2)---任务调度Task Schedule
  • 根据当前日期获取前一天日期-小工具
  • 金仓数据库KingbaseES客户端应用参考手册--12. sys_dumpall
  • 最详细说明spring cloud和Spring Cloud Alibaba的联系和区别
  • 【0基础学算法】二分查找 (超详细讲解+私人笔记+源码)
  • php的引用
  • 网络传输文件的问题
  • Angular4 模板式表单用法以及验证
  • CAP 一致性协议及应用解析
  • Cumulo 的 ClojureScript 模块已经成型
  • docker容器内的网络抓包
  • GitUp, 你不可错过的秀外慧中的git工具
  • javascript 总结(常用工具类的封装)
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • MySQL QA
  • rc-form之最单纯情况
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 微服务入门【系列视频课程】
  • 移动端唤起键盘时取消position:fixed定位
  • 用jQuery怎么做到前后端分离
  • ​【已解决】npm install​卡主不动的情况
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • #pragma预处理命令
  • (12)目标检测_SSD基于pytorch搭建代码
  • (js)循环条件满足时终止循环
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (十八)SpringBoot之发送QQ邮件
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .Net6使用WebSocket与前端进行通信
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .net中应用SQL缓存(实例使用)
  • @Valid和@NotNull字段校验使用
  • [ABP实战开源项目]---ABP实时服务-通知系统.发布模式
  • [Android 13]Input系列--获取触摸窗口
  • [AutoSar]BSW_Com02 PDU详解
  • [BZOJ] 2006: [NOI2010]超级钢琴
  • [CERC2017]Cumulative Code
  • [hdu 4405] Aeroplane chess [概率DP 期望]
  • [HTML]HTML5实现可编辑表格