MySQL事务的隔离级别详情

作者:hqx 时间:2024-01-27 23:33:56 

一、隔离级别的概念

为什么要考虑隔离级别?

因为事务要并发执行,而并发执行可能会出现一些问题:脏读、不可重复读和虚读,有的是允许出现的,有的不允许出现,对于这种不同程度上的出现或不出现的并发控制才有了不同的隔离级别。

MySQL支持的四种隔离级别是:

  • TRANSACTION_READ_UNCOMMITTED:未提交读。说明在提交前事务A可以看到事务B的变化。这样读脏数据,不可重复读和幻读都是被允许的。

  • TRANSACTION_READ_COMMITTED:已提交读(oracle默认),说明读取未提交的数据是不允许的(防止脏读)。在这个级别仍然允许不可重复读和幻读发生。

  • TRANSACTION_REPEATABLE_READ:可重复读(MySQL默认),说明事务保证能够再次读取相同的数据而不会失败,即使其他的事务把这个数据改了,你也不会看到前后两次查询的数据的不同。但是幻读仍然会出现。

  • TRANSACTION_SERIALIZABLE:串行化,是最高的事务隔离级别,它防止脏读,不可重复读和幻读。串行执行,相当于是单线程操作,并发能力最低

MySQL事务的隔离级别详情

注意:

事务隔离级别越高,为避免冲突所花费的性能也就越多,即效率低。在“可重复读”级别,实际上可以解决部分的虚读问题,但是不能防止update更新产生的虚读问题,要禁止虚读产生,还是需要设置串行化隔离级别。

MySQL客户端默认工作在可重复读级别:

MySQL事务的隔离级别详情

二、测试TRANSACTION_READ_UNCOMMITTED隔离级别

MySQL事务的隔离级别详情

MySQL事务的隔离级别详情

若此时A客户端rollback,数据库中zhangsan的年龄恢复到了20,这时候已经来不及了,因为B客户端已经拿着21去做业务了。

MySQL事务的隔离级别详情

两个客户端都rollback放弃对当前事务对数据做的修改,zhangsan年龄恢复为20

MySQL事务的隔离级别详情

三、测试TRANSACTION_READ_COMMITTED隔离级别

MySQL事务的隔离级别详情

MySQL事务的隔离级别详情

因为设置了已提交读隔离级别,所以事务B并没有发生脏读,这是由各种锁机制以及事务并发的MVCC版本控制实现的。

MySQL事务的隔离级别详情

查询到了已经commit的数据,发生了不可重复读,这在已提交读隔离级别是允许发生的。既然发生了不可重复读,幻读就肯定可以发生了。

四、测试TRANSACTION_REPEATABLE_READ隔离级别

MySQL事务的隔离级别详情

MySQL事务的隔离级别详情

可重复读在一定意义上可以防止幻读的出现,可以看到,当前的可重复读隔离级别,防止了insert。其实可重复读隔离级别可以防止insert和delete,不能防止update。

MySQL事务的隔离级别详情

实际上,事务A已经插入并且提交了,aaa已经存在,因为事务B update aaa的年龄成功了

前后两次同样的查询,后一次查询与前一次查询的数据量不同,就发生了幻读。也就是可重复读隔离级别下,并没有解决幻读的问题,要彻底解决幻读,就需要设置串行化隔离级别

五、测试TRANSACTION_SERIALIZABLE隔离级别

MySQL事务的隔离级别详情

MySQL事务的隔离级别详情

从现象看,串行化可以解决幻读,同样的条件进行查询,在另一个表里面插入数据时就被阻塞,由于事务B正在读数据,此时事务A再写数据就被阻塞了(用读写锁实现,允许读读,不允许读写或者写写)

MySQL server不会让自己执行事务的线程永远阻塞,导致当前线程占用的锁无法释放,而使得其他执行事务的线程也无法获得锁而永远阻塞。所以执行事务的线程都是带有时间的,当线程等待时间过长时,会让超时线程释放锁,并会返回一个错误:

MySQL事务的隔离级别详情

来源:https://blog.csdn.net/qq_41721746/article/details/125253363

标签:MySQL,事务,隔离,级别
0
投稿

猜你喜欢

  • 以SQLite和PySqlite为例来学习Python DB API

    2023-07-13 02:19:14
  • python3去掉string中的标点符号方法

    2021-06-27 01:29:45
  • MySQL简化输入小技巧

    2024-01-13 15:49:33
  • MySQL 5.0.16的乱码问题解决方法

    2011-12-14 18:33:24
  • python中pycurl库的用法实例

    2021-05-21 10:10:23
  • Go微服务网关的实现

    2023-07-02 22:27:05
  • 基于pdf2docx模块Python实现批量将PDF转Word文档的完整代码教程

    2022-06-24 15:55:02
  • 详解MySQL中的pid与socket

    2024-01-26 15:07:56
  • node.js中的fs.statSync方法使用说明

    2024-05-13 10:05:29
  • golang时间/时间戳的获取与转换实例代码

    2023-09-02 06:04:43
  • 单步调试 step into/step out/step over 区别说明

    2022-03-09 20:03:26
  • Python 工具类实现大文件断点续传功能详解

    2022-11-17 05:41:29
  • 提高python代码可读性利器pycodestyle使用详解

    2023-09-04 11:22:04
  • python脚本实现统计日志文件中的ip访问次数代码分享

    2021-03-17 08:40:08
  • GoFrame框架gcache的缓存控制淘汰策略实践示例

    2023-07-22 06:41:19
  • Python在游戏中的热更新实现

    2022-04-05 14:10:15
  • python爬虫的一个常见简单js反爬详解

    2022-10-26 11:46:27
  • Python+selenium实现趣头条的视频自动上传与发布

    2022-03-23 10:27:43
  • Python venv虚拟环境配置过程解析

    2021-11-30 20:21:48
  • js处理括弧配对替换的方法

    2008-01-16 13:48:00
  • asp之家 网络编程 m.aspxhome.com