当前位置: 首页 > news >正文

(四十四)多个事务更新同一行数据时,是如何加锁避免脏写的?

之前我们已经用很多篇幅给大家讲解了多个事务并发运行的时候,如果同时要读写一批数据,此时读和写时间的关系是如何协调的,毕竟要是你不协调好的话,可能就会有脏读、不可重复读、幻读等一系列的问题。

简单来说,脏读、不可重复读、幻读,都是别人在更新数据的时候,你怎么读的问题,读的不对,那就有问题,读的方法对了,那就不存在这一系列问题了。

而你要解决这一系列问题,其实就是依靠之前我们给大家讲的那套,基于undo log版本链条以及ReadView实现的mvcc机制。

现在开始我们接下来要用一系列的篇幅来研究另外一个问题了,那就是当有多个事务同时并发更新一行数据的时候,不就是会有脏写的问题吗?

我们之前讲过,脏写是绝对不允许的,那么这个脏写是靠什么防止的呢?

说白了,就是靠锁机制,依靠锁机制让多个事务更新一行数据的时候串行化,避免同时更新一行数据,今天我们就先对数据库的锁机制做一个初步的入门讲解。

在MySQL里,假设有一行数据摆在那儿不动,此时有一个事务来了要更新这行数据,这个时候他会先琢磨一下,看看这行数据此时有没有人加锁?

一看没人加锁,太好了,说明他是第一个人,捷足先登了。

此时这个事务就会创建一个锁,里面包含了自己的trx_id和等待状态,然后把锁跟这行数据关联在一起。

同时大家应该还记得,更新一行数据必须把他所在的数据页从磁盘文件里读取到缓存页里来才能更新的,所以说,此时这行数据和关联的锁数据结构,都是在内存里的,大家要明确这一点,如下图。

image-20230108130721842

大家注意看上面的那个图,因为事务A给那行数据加了锁,所以此时就可以说那行数据已经被加锁了

那么既然被加锁了,此时就不能再让别人访问了!如果有朋友对加锁的概念不了解,可能是对编程语言不太了解,其实这个就跟Java里的加锁是一个概念。

现在呢,有另外一个事务B过来了,这个事务B就也想更新那行数据,此时就会检查一下,当前这行数据有没有别人加锁

然而他一下子发现,真是糟糕啊,事务A这家伙太不地道了,居然抢先给这行数据加锁了,这怎么办呢?

事务B这个时候一想,那行,我也加个锁,然后等着排队不就得了,这个时候事务B也会生成一个锁数据结构,里面有他的trx_id,还有自己的等待状态,但是他因为是在排队等待,所以他的等待状态就是true了,意思是我在等着呢,如下图。

image-20230108130744649

接着事务A这个时候更新完了数据,就会把自己的锁给释放掉了。锁一旦释放了,他就会去找,此时还有没有别人也对这行数据加锁了呢?他会发现事务B也加锁了

于是这个时候,就会把事务B的锁里的等待状态修改为false,然后唤醒事务B继续执行,此时事务B就获取到锁了,如下图。

image-20230108130803117

上述就是MySQL中锁机制的一个最基本的原理,大家可以先好好理解一下,其实是跟Java里的锁机制,思路是完全类似的,从这种简单的锁里可以引申出很多其他的概念,比如读写锁,共享锁,独占锁,公平锁,非公平锁,等等。Java里的锁,也同样具备这些锁的概念。

http://www.lryc.cn/news/20993.html

相关文章:

  • 【数据库】第十二章 数据库管理
  • Redis源码---整体架构
  • 基于springboot+vue的校园招聘系统
  • SAP MM学习笔记1-SAP中扩张的概念,如何将一个物料从工厂A扩张到工厂B
  • 【Python】Numpy数组的切片、索引详解:取数组的特定行列
  • 2023年全国最新交安安全员精选真题及答案6
  • JavaScript 闭包【自留】
  • 【MySQL】什么是意向锁 IS IX 及值得学习的思想
  • python多线程实现
  • macOS使用CodeRunner快速配置fortran环境
  • 【云原生】k8s 离线部署讲解和实战操作
  • 【Kubernetes】第十一篇 - 滚动发布的介绍与实现
  • 【尊享版】如何系统构建你的思维认知模型?
  • urho3D编码约定
  • Overleaf推广奖励:增加合作者的数量、解锁Dropbox同步和项目修改历史
  • ChatGPT的互补工具Perplexity的详细使用方法(持续更新)
  • 【Linux驱动开发100问】如何编译Linux内核?
  • 15、条件概率、全概率公式、贝叶斯公式、马尔科夫链
  • Eureka服务注册与发现
  • 20230226 引用类型和指针类型的区别 - chatGPT
  • 《操作系统》——第二章 进程与线程
  • 网络原理之初识
  • CAN总线开发一本全(4) - FlexCAN的驱动程序
  • 如何分析linux tcp/ip 丢包问题
  • 旅游规划(树型dp)
  • 【C++】string类的模拟实现
  • 笔记(一)——STL容器
  • 红黑树
  • RIP路由协议的更新(电子科技大学TCP/IP第二次实验)
  • 基于JWT实现用户身份认证