- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章关于Mysql隔离级别、锁与MVCC介绍由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文意在弄清楚这些概念间的关系及其作用。弄清Mysql在开启事务的情况下,每条sql执行时的加锁操作和MVCC版本控制。为使讨论简单,本文忽略了GAP锁(间隙锁、范围锁).
我们经常所高并发,高可用。就是从质和量来评估,任何事物都可以从这两个角度来分析。在Mysql数据库中,事务就是用来保证质的,MVCC就是用来保证量的.
。
我们使用事务来保证每一条SQL语句的结果执行符合我们的预期。我们说事务必须具备ACID特性。ACID中的三者:原子性、一致性和持久性其实描述的都差不多,保证SQL执行结果的可靠性。而隔离性就比较复杂了,隔离性描述的是在并发场景下数据库的表现,但并发量并不是固定的,而不同的业务可能有不同的需求,为了使数据库能适应不同的并发场景,所以伟大的人们又定义了四种隔离级别:Read Uncommited,Read Committed (RC),Repeatable Read (RR),Serializable。随着数据库隔离级别的提高,数据的并发能力也有所下降.
。
我们这里只讨论共享锁和排它锁这两概念,读加共享锁,写加排它锁:
在RC隔离级别下,修改数据会加排它锁,事务结束释放,其他事务不许读,解决脏读问题。(共享锁当场释放) 在RR隔离级别下,读数据加共享锁,事务结束释放,其他事务不许修改,解决不可重复读。(共享锁事务结束释放) 。
实际上都把操作串行化了。而Mysql对其进行了优化,一个事务读时其他事务不能写,一个事务写时其他事务不能读?我不这么干照样能解决脏读和不可重复读问题。MVCC出现了。(这也使得问题变得越来越复杂,而不一样的地方也开始出现在RR隔离级别下,碰巧Mysql的默认隔离级别就是RR) 。
。
MVCC即多版本并发控制,使用了双版本号来解决数据的隔离问题。(“create”一个版本号,“delete”一个版本号,修改操作拆分为“delete”和“create”)每个事务在开始对每张表增删改查操作时都会生成一个版本号,每个事务只能查到“create”小于本版本号和“delete”大于本版本号的数据。这样,增删查操作就完全可以并发进行了,只有修改操作是一定要排队的。这样,就算没有共享锁也解决了不可重复读问题,因为其他事务修改后,数据的版本号比我大,我不会读到.
。
引入MVCC之后,看似很美好。然而大家有没有想过两个事务先后对一条数据做更新操作,然后两个事务再读取那条数据,分别读到什么?哈哈,这根本是不可能出现的,因为修改操作是串行的,另一个事务必须先commit本事务才能修改。好,换个问题,两个事务先后对一条数据做+1操作,另一个事务提交后,本事务再+1,再读取那条数据,本事务是读取到+1还是+2的结果?如果读取到+2,那不是破坏了隔离性,读到了其他事务提交的数据么?
然而事实确实是这样,其他事务已经提交,本事务也已修改过那条数据了,之后当然要读到+2才行。虽然本来是0,本事务明明只加了1,可读取后却变成2了,有点不适应。确实,在标准的RR隔离级别下,因为操作都是串行的,本事务读取一行数据后,其他事务就不能修改这条数据了,这条数据永远只有本事务在操作,所以严格满足隔离性。但是Mysql的RR增强了读与写的并发,只有当两个事务同时修改一条数据需要串行,其他所有操作都可以并行。所以造成了这种结果,好像出现了不可重复读。但是这种不可重复读实际上是符合我们的直观感受的,在本事务对数据修改后,当然要读取到最新的数据.
要对其过程进行分析的话:
数据create版本号为0 。
事务1版本号为1,读取数据value=0 。
事务2版本号为2,修改数据value+1=1,原数据delete版本号为2,新数据create版本号更新为2,commit 。
事务1修改数据value+1=2,(由于修改是当前读,永远读取版本号最大的数据,所以读取到value为1)修改后delete版本号为1, 。
新数据create版本号为1 。
本事务读取数据value=2 。
深入分析:
其实上面的描述也是有漏洞的,如果有第三个事务版本号为3呢?因为版本号为3,是不是可以直接读取事务1、2未提交的数据?实际上在MVCC中,每个事务还有一个最低可见版本low_limit_id(事务号 >= low_limit_id的记录,对于当前事务都是不可见的),把当前正在执行还没commit的事务给过滤掉了。例如事务3,虽然版本号为3,但是low_limit_id=1,所以事务1和事务2的修改对3都是不可见的.
总结 。
为了解决隔离性问题,都没有使用完全copy数据这种笨方法。传统数据库使用共享锁和排它锁使读写操作串行;Mysql使用MVCC和排它锁,读写可并行。Mysql在RR隔离级别以下,和传统方式表现一致,在RR隔离级别,和传统方式有差异,体现在本事务更新某条数据后,能读取到其他事务对该条数据已提交的修改.
原文链接:https://www.cnblogs.com/jieqing/p/8328074.html 。
最后此篇关于关于Mysql隔离级别、锁与MVCC介绍的文章就讲到这里了,如果你想了解更多关于关于Mysql隔离级别、锁与MVCC介绍的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
一、公平锁和非公平锁 1.1、公平锁和非公平锁的概述 公平锁:指多个线程按照申请锁的顺序来获取锁。 非公平锁:指在多线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取到锁
阅读目录 1、简介 2、分类 3、全局锁 4、表级锁 5、表锁 6、元数据锁
因此,在我编写的程序中,我有三个函数,为了简单起见,我们将它们称为 A、B 和 C。每个函数都需要访问资源X才能工作。 限制是A和B不允许同时运行并且必须适当同步。但是,C 可以与 A 或 B 同时运
我听说过这些与并发编程相关的词,但是锁、互斥量和信号量之间有什么区别? 最佳答案 锁只允许一个线程进入被锁定的部分,并且该锁不与任何其他进程共享。 互斥锁与锁相同,但它可以是系统范围的(由多个进程共享
这个问题已经有答案了: What is an efficient way to implement a singleton pattern in Java? [closed] (29 个回答) 已关闭
这个问题已经有答案了: What is an efficient way to implement a singleton pattern in Java? [closed] (29 个回答) 已关闭
我对标题中的主题有几个问题。首先,假设我们使用 JDBC,并且有 2 个事务 T1 和 T2。在 T1 中,我们在一个特定的行上执行 select 语句。然后我们对该行执行更新。在事务 T2 中,我们
我希望我的函数只运行一次。这意味着如果多个线程同时调用它,该函数将阻塞所有线程,只允许它运行。 最佳答案 听起来您希望存储过程进行同步。为什么不直接将同步放在应用程序本身中。 pthread_mute
if (runInDemoMode) { lock (this) { //Initalization of tables dCreator.create
我相信无论使用什么语言都可以考虑我的问题,但是为了有一些“ anchor ”,我将使用 Java 语言来描述它。 让我们考虑以下场景:我有一个扩展 Thread 的类 PickyHost 及其实例 p
我知道异步不是并行的,但我现在遇到了一个非常有趣的情况。 async function magic(){ /* some processing here */ await async () =
我们正在使用 Scala、Play 框架和 MongoDB(以 ReactiveMongo 作为我们的驱动程序)构建一个网络应用程序。应用程序架构是端到端的非阻塞。 在我们代码的某些部分,我们需要访问
我需要一个简单的锁,JavaME 超时(concurrent.lock 的反向移植需要完整的 Java 1.3)。 如果其他人已经为 JavaME 发布了经过测试的锁定代码,我宁愿使用它。 锁定是出了
根据 boost : To access the object, a weak_ptr can be converted to a shared_ptr using the shared_ptr co
关于 Mutex 和 Critical 部分之间的区别存在一个问题,但它也不处理 Locks。 所以我想知道临界区是否可以用于进程之间的线程同步。 还有信号状态和非信号状态的含义 最佳答案 在 Win
锁 最为常见的应用就是 高并发的情况下,库存的控制。本次只做简单的单机锁介绍。 直接看代码: 每请求一次库存-1. 假如库存1000,在1000个人请求之后,库存将变为0。
线程和进程 1、线程共享创建它的进程的地址空间,进程有自己的地址空间 2、线程可以访问进程所有的数据,线程可以相互访问 3、线程之间的数据是独立的 4、子进程复制线程的数据 5、子进程启动
**摘要:**细心的你也一定关注到,有的网址是https开头的,有的是http。https开头的网站前面,会有一把小锁。这是为什么呢? 本文分享自华为云社区《还不知道SSL证书已经是刚需了?赶快来了解
试图在 C 中实现一个非常简单的互斥锁(锁)我有点困惑。我知道互斥锁类似于二进制信号量,除了互斥锁还强制执行释放锁的线程的约束,必须是最近获得它的同一线程。我对如何跟踪所有权感到困惑? 这是我到目前为
在阅读了很多与上述主题相关的文章和答案之后,我仍然想知道 SQL Server 数据库引擎在以下示例中是如何工作的: 假设我们有一个名为 t3 的表: create table t3 (a int ,
我是一名优秀的程序员,十分优秀!