- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章啥是 MySQL 事务隔离级别?由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
之前发过一篇文章,简单了解 MySQL 中相关的锁,里面提到了,如果我们使用的 MySQL 存储引擎为 InnoDB ,并且其事务隔离级别是 RR 可重复读的话,是可以避免幻读的.
但是没想到,都 1202 年了都还有人杠,说 InnoDB 的 RR 隔离级别下会出现幻读,只能依靠 gap 和 next-key 这两个锁来防止幻读 ,最开始我还以为是他真的不知道这个点,就跟他聊,最后聊下来发现,发现是在钻牛角尖.
这个在下面讲到 可重复读 的隔离级别时会讲.
本来我觉得事务隔离级别这玩意儿太简单没啥可讲的,但是经过了上面这件事,我打算详细的把事务隔离给讲讲。接下来顺便就把 InnoDB 所有的事务隔离级别给搂一遍.
ACID 。
在聊事务隔离级别之前,我们需要知道 ACID 模型.
ACID 模型 。
分别代表:
原子性,代表 InnoDB 事务中,所有的操作要么全部成功,要么全部失败,不会处于某个中间状态。说的更通俗一点,如果事务 A 失败,其所做的所有的更改应该全部回滚.
一致性,主要是保护数据的一致性,防止由于数据库的崩溃而导致的数据一致性问题。举个例子,我们更新 MySQL 的数据,更新的数据会先到 InnoDB 的 Buffer Pool 中,如果此时 MySQL 所在的机器突然意外重启了,如果 InnoDB 没有崩溃恢复机制,之前更新的数据就会丢失,数据的一致性问题就出现了.
很多其他的博客写的是事务开要始前后,数据的完整性没有被破坏。我表示看了根本看不懂,太抽象了.
隔离性,主要是指事务之间的隔离,再具体一点,就是我们本篇文章要讨论的事务隔离级别了.
持久性,主要是指我们新增或者删除了某些数据,一旦成功,这些操作应该需要被持久化到磁盘上去.
ACID 模型可以理解成数据库的设计范式,主要关注点在数据数据、及其本身的可靠性。而 MySQL 中的 InnoDB 就完全遵守 ACID 模型,并且在存储引擎层就支持数据一致性的校验和崩溃恢复的机制.
而 ACID 中的隔离型,就是我们这篇文章中讨论的重点.
事务隔离级别 。
有很多文章上来就直接介绍事务隔离级别的种类,这个种类啥意思,那个种类怎么用。但我认为应该先了解为什么需要事务隔离级别,以及事务隔离级别到底解决了什么问题,这才是关键.
我们知道 InnoDB 中同时会有多个事务对数据进行操作,举一些例子:
以上的这些问题,就需要事务隔离级别来回答了。其实以上的三种情况分别对应不可重复读、脏读和幻读。InnoDB 通过事务隔离级别分别的解决了上面的问题。所有的事务隔离级别如下:
InnoDB 默认的事务隔离级别为 REPEATABLE READ .
读未提交 。
事务A读取了事务B还未提交的数据 。
如果事务B此时出错了进行了回滚,那么事务A读取到的数据就成为了脏数据,从而造成脏读.
如果事务B又更新事务A读取的数据,那么事务A再次读取,读取到了事务B修改的结果,这造成了不可重复读.
而如果事务B又新增了数据,事务A再次读取,会读取到事务B新增的数据,这造成了幻读.
所以总结来说,在读未提交这个隔离级别下,会造成以下的问题:
读已提交 。
事务A读取了事务B已经提交的数据 。
如果事务B更新了事务A读取到的数据,并且提交,那么当事务A再次进行读取,就会读取到其他事务的变更,就造成了不可重复读.
同理,如果事务B新增了数据并且提交,事务A再次进行读取时拿到了事务B刚刚提交的数据,这就造成了幻读.
所以总结来说,在读已提交的隔离级别下,会造成:
可重复读 。
事务A不会读取到事务B更新的数据,也不会读到事务B新增的数据 。
在可重复读场景下,不会出现脏读、不会出现不可重复读,可能会出现幻读.
无论事务B做了什么操作,事务A查询到的 id=1 的数据都是张三.
但是,在某些情况下,还是可能会出现 幻读。可重复读 只是在某些情况下会产生幻读,但绝对不是 InnoDB 无法避免幻读。首先,InnoDB 在 RR 隔离级别下有很明确的解决幻读的方式,那就是——临键锁,一种组合了 gap 锁和记录锁的锁.
接下来举个例子来看在 RR 隔离级别下,什么情况会出现幻读,什么情况下不会出现幻读。首先是 可能会出现幻读.
由于 InnoDB 有 MVCC 来进行多事务的并发,此时 SELECT 走的是快照读,不会加锁,那么临键锁就无法发挥其作用,如果有其他事务插入了一条数据,那么事务再次执行上面的语句是有可能会查出 id > 1 的数据.
但是如果显示的进行加锁,则可以避免这个问题.
至于为什么临键锁可以避免幻读,之前的文章已经聊的很清楚,就不在此赘述了.
串行化 。
所以事务被强制的串行执行 。
这样从根本上就避免了并发的问题,但是这样会使得 MySQL 的性能下降。因为现在同一时间只能有一个事务在运行.
EOF 。
关于事务隔离级别就先介绍到这,之后有时间了就把 事务隔离级别 的底层原理给搂一遍.
原文地址:https://mp.weixin.qq.com/s/VAfR8MVw18Yt-sfe4t22NQ 。
最后此篇关于啥是 MySQL 事务隔离级别?的文章就讲到这里了,如果你想了解更多关于啥是 MySQL 事务隔离级别?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
Android 项目中最低(最低 sdk)和最高(目标 sdk)级别是否有任何影响。这些东西是否会影响项目的可靠性和效率。 最佳答案 没有影响,如果您以 SDK 级别 8 为目标,那么您的应用将以 9
我将现有的 android 项目升级到 API 级别 31。我使用 Java 作为语言。我改变了 build.gradle compileSdkVersion 31 defaultConfig {
我正在使用 ionic 3 创建一个 android 应用程序,当我尝试上传到 playstore 时,我收到一个错误,提示我的应用程序以 api 25 为目标,当我检查我的 project.prop
我刚刚尝试将应用程序的目标和编译 API 级别更新为 29 (Android 10),并注意到我无法再编译,因为 LocationManager.addNmeaListener 只接受 OnNmeaM
我的代码没有在 Kitkat 上显示工具栏。 这是我的两个 Android 版本的屏幕截图。 Kitkat 版本: Lollipop 版: 这背后的原因可能是什么。 list 文件
我正在构建面向 API 级别 8 的 AccessabilityService,但我想使用 API 级别 18 中引入的功能 (getViewIdResourceName())。这应该可以通过使用 A
当我想在我的电脑上创建一个 android 虚拟机时,有两个选项可以选择目标设备。它们都用于相同的 API 级别。那么我应该选择哪一个呢?它们之间有什么区别? 最佳答案 一个是基本的 Android,
当我选择 tagret 作为 Android 4.2.2(API 级别 17)时,模拟器需要很长时间来加载和启动。 所以我研究它并通过使用 找到了解决方案Intel Atom(x86) 而不是 ARM
我有一个使用 Android Studio 创建的 Android 项目。我在项目中添加了一些第三方依赖项,但是当我尝试在 Android Studio 中编译时,我遇到了以下错误: Error:Ex
如上所述,如何使用 API 8 获取移动设备网络接口(interface)地址? 最佳答案 NetworkInterface.getInetAddresses() 在 API8 中可用。 关于andr
我想显示 Snackbar并使用图像而不是文本进行操作。 我使用以下代码: val imageSpan = ImageSpan(this, R.drawable.star) val b
我有一个用 python 编写的简单命令行程序。程序使用按以下方式配置的日志记录模块将日志记录到屏幕: logging.basicConfig(level=logging.INFO, format='
使用下面的代码,实现游戏状态以控制关卡的最简单和最简单的方法是什么?如果我想从标题画面开始,然后加载一个关卡,并在完成后进入下一个关卡?如果有人能解释处理这个问题的最简单方法,那就太好了! impor
我想创建一个可以找到嵌套树结构深度的属性。下面的静态通过递归找出深度/级别。但是是否可以将此函数作为同一个类中的属性而不是静态方法? public static int GetDepth(MenuGr
var myArray = [{ title: "Title 1", children: [{ title: "Title 1.1", children: [{
通过下面的代码,实现游戏状态来控制关卡的最简单、最容易的方法是什么?如果我想从标题屏幕开始,然后加载一个关卡,并在完成后进入下一个关卡?如果有人可以解释处理这个问题的最简单方法,那就太好了! impo
我有一个树结构,其中每个节点基本上可以有无限个子节点,它正在为博客的评论建模。 根据特定评论的 ID,我试图找出该评论在树中的深度/级别。 我正在关注 this guide that explains
考虑任何给定的唯一整数的数组,例如[1,3,2,4,6,5] 如何确定“排序度”的级别,范围从 0.0 到 1.0 ? 最佳答案 一种方法是评估必须移动以使其排序的项目数量,然后将其除以项目总数。 作
我如何定义一个模板类,它提供一个整数常量,表示作为输入模板参数提供的(指针)类型的“深度”?例如,如果类名为 Depth,则以下内容为真: Depth::value == 3 Depth::value
我的场景是:文件接收器应该包含所有内容。另一个接收器应包含信息消息,但需要注意的是 Microsoft.* 消息很烦人,因此这些消息应仅限于警告。两个sink怎么单独配置?我尝试的第一件事是: str
我是一名优秀的程序员,十分优秀!