事务的 4 个隔离级别

一、事务的 4 个隔离级别

  • 未提交读(Read Uncommitted):事务可以读取未提交的数据,也称作脏读(Dirty Read)。一般很少使用。

  • 提交读(Read Committed):是大都是 DBMS (如:Oracle, SQLServer)默认事务隔离。执行两次同意的查询却有不同的结果,也叫不可重复读。

  • 可重复读(Repeable Read):是 MySQL 默认事务隔离级别。能确保同一事务多次读取同一数据的结果是一致的。可以解决脏读的问题,但理论上无法解决幻读(Phantom Read)的问题。

  • 可串行化(Serializable):是最高的隔离级别。强制事务串行执行,会在读取的每一行数据上加锁,这样虽然能避免幻读的问题,但也可能导致大量的超时和锁争用的问题。很少会应用到这种级别,只有在非常需要确保数据的一致性且可以接受没有并发的应用场景下才会考虑。

    solation Level脏读可能性(Dirty Read)不可重复读可能性(Non Repeatable Read)幻读可能性(Phantom Read)
    ead UncommittedYesYesYes
    ead Committed-YesYes
    epeatable Read--Yes
    erializable---

二、测试:模拟异常发生

我们通过两个客户端(A 和 B)测试模拟一下这三种异常(脏读、不可重复读和幻读)。

  • 准备工作

    1、首先我们操作客户端 A 查看当前隔离级别。

    2、可以看到当前的隔离级别是 REPEATABLE-READ,也就是可重复读。那么接下来我们要把它切换为未提交读(READ UNCOMMITTED)方便测试。

    3、切换完成后,我们还需要设置 autocommit 参数为 0 ,因为 MySQL 是默认自动提交事务的。

    4、然后我们操作客户端 B 以刚才客户端 A 同样的操作实现切换隔离级别为 READ UNCOMMITTED 和 autocommit 为 0。

    5、最后准备一个数据表测试数据就完成了准备工作,我这里新建了个students数据表用来测试。

  • 脏读

    事务 A 往测试表新增了一条数据,而事务 B 查询测试表时,读到事务 A 新增了却还未提交的数据。如果事务 A 回滚,那么事务 B 读到的数据就是脏数据。

    步骤事务 A事务 B注释
    1BEGIN;BEGIN;开启事务。
    2INSERT INTO students VALUES (5, ‘赵六’);事务 A 新增一条数据。
    3SELECT * FROM students;事务 B 读到了事务 A 新增却还没提交的数据。
    4ROLLBACK;要是这时事务 A 回滚操作。
    5SELECT * FROM students;事务 B 再次查询发现已经没有了「赵六」的数据。
    6COMMIT;提交事务。
    • 事务 A 回滚前,事务 B 查询到的结果。

    • 事务 A 回滚后,事务 B 查到的结果。

  • 不可重复读

    同一事务两次查询读取同一数据,得到的结果不一致。

    步骤事务 A事务 B注释
    1BEGIN;BEGIN;开启事务。
    2SELECT name FROM WHERE id = 1;事务 B 查询 id = 1 的是「张三」。
    3UPDATE students SET name = ‘张三三’ WHERE id = 1;事务 A 修改 id = 1 为「张三三」。
    4COMMIT;提交事务 A。
    5SELECT name FROM WHERE id = 1;事务 B 再次查询 id = 1 的已经改成「张三三」。
    COMMIT;提交事务 B。
    • 事务 A 修改数据前,事务 B 查到的结果。

    • 事务 A 修改数据后,事务 B 查到的结果。

  • 幻读

    同一事务两次查询同一范围数据,得到的结果不一致。幻读是不可重复读的一种特殊情景,事务 A 查询某条件范围的数据,而事务 B 正在修改此条件范围的数据。

    步骤事务 A事务 B注释
    1BEGIN;BEGIN;开始事务。
    2SELECT * FROM students WHERE id BETWEEN 1 AND 5;事务 B 查询某范围内的数据。
    3INSERT INTO students VALUES (4, ‘赵六’);事务 A 新增一条数据。
    4COMMIT;提交事务 A
    5SELECT * FROM students WHERE id BETWEEN 1 AND 5;事务 B 再次查询发现数据发生更改。
    • 事务 A 添加数据前,事务 B 查到的结果。

    • 事务 A 添加数据后,事务 B 查到的结果。

三、异常小结

  • 脏读:读取到了其他事务还没提交的数据。

  • 不可重复读:两次查询同一条数据有不同的结果,因为其它事务可能在UPDATE操作。

  • 幻读:事务 B 根据条件查询到了 N 条数据,但这时事务 A INSERTDELETE了 M 条符合事务 B 查询条件的数据。事务 B 再次查询结果就和上一次不一致了,得到了 N+M 条数据。

    不可重复读和幻读的区别

    • 不可重复读:是同一数据内容被修改了,是 UPDATE操作。
    • 幻读:某一个范围内的数据行数变多了或变少了,是 INSERTDELETE 操作。
  • 17
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值