MySQL InnooDB引擎之并发事务问题以及隔离级别的作用和区别
最近在复习MySQL事务,但网上很多博客和资料可以说讲的不是模棱两可就是只有文字描述不够形象易懂,下面通过我的学习来详细讲一讲事务并发都会引起哪些问题?以及隔离级别是什么?InnoDB引擎是如何通过隔离级别来解决并发事务所引起的问题?
何为读已提交
(相当于当前读,也就是这种隔离级别下只要有其他事务对数据进行更改的操作且提交,那么当前事务Select就会查询到最新的数据)
从字面上我们就可以理解,即一个事务操作过程中可以读取到其他事务已经提交的数据。
事务中的每次读取操作,读取到的都是数据库中其他事务已提交的最新的数据(相当于当前读),也就是不能读取到其他事务还未提交的数据,所以在读已提交这个隔离级别下就解决了脏读的问题
何为可重复读
(又称快照读,当事务A开启时便对数据产生一个快照,与此同时无论其他事务对数据如何操作,在当前这个事务A里查询到的都是快照中的数据)(又称快照读,当事务A开启时便对数据产生一个快照,与此同时无论其他事务对数据如何操作,在当前这个事务A里查询到的都是快照中的数据)
一个事务操作中对于一个读取操作不管多少次,读取到的结果都是一样的。所以在可重复读这个隔离级别下就解决了一个事务当中前后读取到的结果不一致的情况,从而解决了不可重复读的问题
下面就通过实际操作来看看脏读,不可重复读,幻读这三个现象是什么样的,以及在InnoDB各个隔离级别下是如何解决了这些并发事务问题的。
脏读现象:
首先设置隔离级别为未提交读
打开两个窗口,同时执行事务A和B
此时事务B更新数据后并未提交,但可以看到事务A前后查询到的数据不一样,也就是读取到了其他事务还未提交的数据,这也就是脏读的现象
如何解决脏读现象:
首先设置隔离级别为已提交读:
打开两个窗口,同时执行事务A和B:
上述流程可以看到当隔离级别为已提交读时,已经解决了脏读的情况,但是当事务B对数据进行更改且提交时,事务A却出现了前后的查询结果不一致的情况,这种现象就叫做不可重复读。
如何解决不可重复读的现象:
首先设置隔离级别为可重复读:
打开两个窗口,同时执行事务A和B:
上述流程可以看到当隔离级别为可重复读时,已经解决了不可重复读的情况,当事务B对数据进行更改且提交时,事务A前后的查询结果一致,只有当事务A提交后再开启事务查询时才会查到最新的数据。
幻读现象:
首先设置隔离级别为可重复读:
打开两个窗口,同时执行事务A和B:
上述流程可以看到当隔离级别为可重复读时,事务A,B同时执行,事务A先查询到id=3是没有数据的于是想要Insert,此时事务B也insert了id=3的数据但是事务A却查询不到,并且当事务A insert的时候却提示了error,这种现象就称为幻读。
如何解决幻读的现象:
首先设置隔离级别为串行化:
打开两个窗口,同时执行事务A和B:
上述流程可以看到当隔离级别为序列化时,事务A,B同时执行,事务A先查询到id=4是没有数据,此时事务B想insert id=4的数据但是却阻塞了,接下来事务A执行了insert id=4d的操作,并且只要事务A不提交事务B都一直处于阻塞状态中,当事务A提交后事务B才不再阻塞,但此时却报错提示id=4已存在,从而解决了幻读的问题。
所以MySQL当中默认的隔离级别是不可重复读,一般也不会去手动更改。
综上所述基本说清楚了在InnoDB引擎当中所产生的并发事务问题,是如何解决的,以及为什么会有隔离级别这个概念,它们之间有什么区别,作用又是什么,希望本篇文章能够帮助大家更有效地理解这一部分的知识。
最新文章
- Linux C编程学习之开发工具3---多文件项目管理、Makefile、一个通用的Makefile
- java条件语句练习题
- BitSet构造函数的两种特例
- SQL 常用的命令 (转)
- Session Storage、Cache Storage
- NLPIR分词工具的使用(java环境下)
- PHP二维数组提取函数----把不需要的数据剔除
- C#调用C++ DLL类方法(转)
- java内部类实现多继承
- 我的学习之路_第三十四章_jsp
- 关于php的命名空间
- 校招:Vobile阜博通2015校园招聘
- Java语言编程 - Java第一个程序HelloWorld
- lua os.date函数定义和示例
- 【BZOJ1426】收集邮票 期望DP
- java.lang.NoSuchMethodException: .<;init>;()
- 分布式缓存技术redis系列(五)——redis实战(redis与spring整合,分布式锁实现)
- TZOJ 2588 Bad Grass(DFS)
- vmware workstation 下安装ubuntu
- linux指定某非root用户执行开机启动项的方法(gogs git)
热门文章
- Docker问题:";docker build"; requires exactly 1 argument.
- 使用Dockfile构建mysql镜像与初始化运行mysql容器
- 【设计模式】Java设计模式 - 外观模式
- Docker(一):初识
- 利用Kafka的Assign模式实现超大群组(10万+)消息推送
- ProxySQL Disk库和Stats库
- 使用 Elastic 技术栈构建 K8S 全栈监控 -1:搭建 ElasticSearch 集群环境
- tcmalloc 动态库替换(CentOS 操作系统)
- 使用 Auditbeat 模块监控 shell 命令
- k8s中pod的容器日志查看命令