• MySql隔离级别知识点整理



    深入理解sql隔离级别:

    通过举例理解sql隔离级别以及事务并发会出现的情况,告别死记硬背

    1. 事务并发出现情况
    2. 事务隔离级别
    3. 事务的四大特性
    4. 坑点:全局隔离级别仅对新的会话生效,因此得多开一个窗口来设置隔离级别

    事务并发情况概念:

    尽量简洁,我们容易记住

    1.脏读(Dirty Read)

    即一个事务读取了另一个事务修改但未提交的数据

    2.不可重复读(Non-Repeatable Read)

    一个事务中多次读取的结果不一致,主要发生了修改

    3.幻读(Phantom)

    一个事务中多次读取的结果不一致,主要发生了新增或删除


    隔离级别:

    举例阐述每种隔离级别出现的情况,就能够更深入地理解三种并发情况

    1.读未提交(READ UNCOMMITTED)

    见名思义,一个事务可以读到另一个事务修改但未提交的数据
    会出现三种情况

    a.脏读

    事务1

    // 1.查看隔离级别 - REPEATABLE READ
    SELECT @@GLOBAL.tx_isolation 
    
    // 2.设置隔离级别 - READ UNCOMMITTED
    set global transaction isolation level READ UNCOMMITTED;
    
    // 5.开启事务
    begin;
    
    // 6.查询到修改但未提交的数据,一旦回滚读到的是不被承认的
    select * from user where user_id = 1;
    
    // 提交
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    事务2

    // 3.开启事务
    begin;
    // 4.修改数据
    UPDATE user set user_name = '修改但我要回滚' where user_id = 1;
    // 7.回滚数据
    ROLLBACK;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    事务1读取的结果
    在这里插入图片描述

    b.不可重复读

    事务1

    // 3.开启事务
    begin;
    
    // 4.第一次查询 -- 修改但要回滚+1
    select * from user where user_id = 1;
    
    // 6.第二次查询 -- 修改但要回滚+2
    select * from user where user_id = 1;
    
    // 8.第三次查询 -- 原数据
    select * from user where user_id = 1;
    
    COMMIT;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    事务2

    // 1.开启事务
    begin;
    
    // 2.第一次修改
    UPDATE user set user_name = '修改但要回滚+1' where user_id = 1;
    
    // 5.第二次修改
    UPDATE user set user_name = '修改但要回滚+2' where user_id = 1;
    
    // 7.回滚
    ROLLBACK;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    事务1第一次读取的结果
    在这里插入图片描述
    事务1第二次读取的结果
    在这里插入图片描述
    事务1第三次读取的结果
    在这里插入图片描述

    c.幻读

    事务1

    // 3.开启事务
    begin;
    
    // 4.第一次查询 整个范围的数据
    select * from user;
    
    // 6.第二次查询 整个范围的数据
    select * from user;
    
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    事务2

    // 1.开启事务
    begin;
    
    // 2.新增
    insert into user values(0,"新增数据")
    
    // 5.回滚
    ROLLBACK;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    事务1第一次查询结果
    在这里插入图片描述
    事务1第二次查询结果
    在这里插入图片描述

    2.读已提交(READ COMMITTED)

    事务只能读到另一个事务已经提交的数据
    会出现以下两种情况

    1.不可重复读

    事务1

    // 1.查看全局隔离级别 - READ-COMMITTED
    SELECT @@GLOBAL.tx_isolation;
    // 2.开启事务
    begin;
    // 5.第一次查询 - 原数据
    select * from user where user_id = 1;
    // 7.第二次查询 - 张三
    select * from user where user_id = 1;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    事务2

    // 3.开启事务
    BEGIN;
    // 4.修改但未提交
    update user set user_name="张三" where user_id = 1;
    // 6.提交
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    事务1第一次查询
    在这里插入图片描述
    事务1第二次查询
    在这里插入图片描述

    2.幻读

    事务1

    // 3.开启事务
    begin;
    // 4.第一次查询全部的
    select * from user ;
    // 6.第二次查询全部的
    select * from user ;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    事务2

    // 1.事务开启
    BEGIN;
    // 2.插入数据
    INSERT into user VALUES(0,"迪迦");
    // 5.提交
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    事务1第一次查询的结果

    在这里插入图片描述
    事务2第二次查询的结果
    在这里插入图片描述

    3.可重复读(REPEATABLE READ)

    一个事务多次查询同一个数据,多次读取的结果一致
    出现以下幻读情况,避免了不可重复读

    1.解决不可重复读

    事务1

    // 1.当前对话的隔离级别-- REPEATABLE-READ
    SELECT @@SESSION.tx_isolation
    // 2.开启事务
    BEGIN;
    // 6.第一次查询 -- 原数据
    SELECT * from user WHERE user_id = 1;
    // 8.第二次查询 -- 原数据
    SELECT * from user WHERE user_id = 1;
    // 9.提交
    COMMIT;
    // 10.第三次查询 -- 李四
    SELECT * from user WHERE user_id = 1;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    事务2

    // 3.查看当前会话 -- REPEATABLE-READ
    SELECT @@SESSION.tx_isolation
    // 4.开启事务
    BEGIN;
    // 5.修改数据
    update user set user_name = "李四" where user_id = 1;
    // 7.提交数据
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    事务1第一次读取的结果
    在这里插入图片描述
    事务1第二次次读取的结果
    在这里插入图片描述
    事务1提交后,读取的结果,提交后事务就算结束了
    在这里插入图片描述

    2.幻读

    事务1

    // 3.开启事务
    BEGIN;
    // 4.第一次查询
    SELECT * from user;
    // 6.第二次查询
    SELECT * from user;
    // 7.修改该范围内的名字
    update user set user_name = 'xxx'
    // 8.第三次查询 -- 多了一条数据
    SELECT * from user;
    
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    事务2

    // 1.开启事务
    BEGIN;
    // 2.添加数据
    INSERT INTO user VALUES(0,"小黑");
    // 5.提交
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    事务1第一次查询结果
    在这里插入图片描述
    事务1第二次查询结果,乍一看觉得没有问题
    在这里插入图片描述
    事务1第三次查询结果,结果多了一条数据
    在这里插入图片描述

    4.可串行化(SERIALIZABLE)

    两个事务中只要有一个有修改操作,就会发生堵塞,串行读取数据,锁争抢严重
    没有所谓幻读问题

    事务的四大特性(ACID)

    1. A(atomicity)原子性:原子是不再分隔的最小工作单元,要么全部失败回滚,要么全部执行
    2. C(consistency)一致性:事务总是从一个状态的一致性到另一个状态的一致性
    3. I(isolated)隔离性:指事务未被提交之前,是不被其他事务所见的
    4. D(durability)持久性:事务只要被提交后,就会永久的保存到数据库
  • 相关阅读:
    CronExpression
    HarmonyOS NEXT应用开发—使用弹簧曲线实现抖动动画及手机振动效果案例
    Java “constant string too long” 编译错误
    来不及细说,毕业三天靠Python兼职赚了两千
    【阿旭机器学习实战】【8】逻辑斯蒂回归原理及实战
    关于 mysql 中没有string_agg函数问题
    使用百度 EasyDL 实现电动车进电梯自动预警
    谷歌实用插件分享
    【学生网页作业】航海王动漫网页 html+ css + JavaScript 简单的学生网页作业源码
    计算机网络总结笔记
  • 原文地址:https://blog.csdn.net/weixin_47729434/article/details/126261564