【MySQL】数据库中锁和事务的相关知识点

news/2024/3/29 20:58:26/文章来源:https://blog.csdn.net/lyx7762/article/details/129259621

1.事务的四大特点

  • 原子性:事务中的所有操作要么都成功,要么都失败。所有的操作是一个不可分割的单位。
  • 一致性:一致性指的是事务执行前后,数据从一个合法性状态转移到另一个合法性状态。这个状态和业务有关,是自己定义的。比如余额不能为负数。一旦事务执行完不满足这个合法性状态,就违反了一致性原则。
  • 隔离性:并发环境下,多个事务同时操作数据库,应该保证多个事物之间互不影响。
  • 持久性:事务一旦提交,那么就会被永久的写入到磁盘中。

总的来说,原子性是基础,隔离性是手段,一致性是约束条件,持久性是目标。


2.事务并发访问数据库会产生的问题

  • 脏写问题:Session A修改了session B中已经修改但是还没有提交的记录,Session A提交了,但是Session B回滚了,Session A再次访问该记录发现自己修改的记录没有生效。
  • 脏读问题:事务A读取了已经被事务B修改但是还没有提交的数据。之后如果事务B进行回滚,那么事务A读取到的数据就是无效的。
  • 不可重复读:事务A读取了某一条记录,事务B修改了这个记录,然后事务A再次读取发现结果变了,这就是不可重复度。
  • 幻读:事务A查询年龄大于10岁的人,事务B正好修改这一部分记录,事务A再次按照相同条件查询发现结果和之前查询不一致了,这就是幻读。

3.SQL中的四种隔离级别

  • 读未提交:所有的事务都可以访问其他事务中修改但是未提交的数据
  • 读已提交:一个事务只能读取到其他事务已经提交的数据;可以避免脏读
  • 可重复读:事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容。可以避免脏读、不可重复读,但幻读问题仍然存在。在这个事务执行期间,禁止其他事务对相应字段写操作
  • 序列化:可串行化,确保事务可以从一个表中读取相同的行。在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作。所有的并发问题都可以避免,但性能十分低下。在这个事务执行期间,禁止其他事务对整个表进行写操作

4.锁结构

  • 锁结构包含两个重要属性:创建锁的事务id和is_waiting字段
  • 当一个事务要访问某一条记录的时候,会首先生成一个锁结构,然后看一看有没有其他锁结构和这条记录关联,如果有,那么is_waiting字段设置为true,否则设置为false
  • 当T1执行完毕后,会释放锁结构,然后看一下这条记录有无关联的锁结构,然后将is_waiting设置为false,唤醒这个事务

5.MySQL中解决并发访问问题的方法

  • MVCC,对写操作进行加锁,读-写 操作彼此并不冲突, 性能更高 。
  • 采用加锁的方式,读-写 操作彼此需要 排队执行 ,影响性能。

6.按照数据类型分类的锁

  • 读锁(S锁 共享锁):允许多个事务同时读取数据。但是读取的时候不允许写入,因此和X锁不兼容
  • 写锁(X锁 排他锁):写的时候即不允许其他的事务写,也不允许其他的事务读。因此和X以及S锁都不兼容

7.什么是锁定读

  • 在使用select语句的时候可以使用lock in share mode 和 for update 分别个这个记录添加读锁和写锁

注意:for update for share 针对的都是select语句,如果是insert update
等操作会自动添加相应的锁,不需要写for …


8.按照锁的粒度去划分,划分为什么锁

  • 表级锁:表级锁和之前的行级锁是一样的区别在于表级锁需要自己手动的去开启和释放,
  • 页锁
  • 行锁:行级锁在commit之后就自动释放了;而行锁需要手动的去释放锁以后锁才会消失

9.意向锁

使用场景

  • 现在又两个事物T1和T2,T2想在表上添加一个表级锁,如果没有意向锁,那么它需要遍历表中所有记录,来查看是否有互斥的行锁存在,如果没有则加表锁。这个遍历过程是非常耗时的。
  • 有了意向锁以后,当T1针对表中的某一条记录添加锁以后,还会在其上层结构中(比如行的上层就是表),添加意向锁IX,此时,当T2要添加表锁时候,直接查看是否存在意向锁即可,大大提高了效率。

特点

  • InnoDB支持不同粒度的锁共存,意向锁就是一个例子,实现了表级锁和行锁的共存
  • 意向锁是表级锁,不会和行级锁发生冲突。只会和表级的X,S锁发生冲突
  • 意向锁在保证并发性的前提下,实现了行锁和表锁的共存,其满足事务的隔离要求

10.其他锁

  • 自增锁
  • MDL元数据锁:如果一个查询正在遍历一个表中的数据,而执行期间另一个线程对这个 表结构做变更 ,增加了一列,那么查询线程拿到的结果跟表结构对不上,肯定是不行的。因此,当对一个表做增删改查操作的时候,加 MDL读锁;当要对表做结构变更操作的时候,加 MDL 写锁。

11.间隔锁

  • 数据库中有四种隔离级别,读未提交,读已提交,可重复读,和串行化,在不同的隔离级别下会出现脏读,不可重复读和幻读的问题。
  • 前三种问题可以通过行锁来解决,但是幻读问题不可以。原因是无法给还没有插入的数据加锁。
  • 为了解决这一个问题,间隔锁就被提出来了。间隔锁实现了在可重复读的隔离级别下避免了幻读的产生
age字段中的值1 4 7 10
那么产生的区间为 (-,1) 1 (1,4) 4 (4,7) 7 (7,10) 10 (10,+)select * from student where age > 5 and age < 8
锁的并不是整个数据库表,而是查找离下限(5)最大的id值和上限(10)最小的id值,分别为415;然后锁的区间范围为(415],
此时会给(4,7] (7,10)加间隙锁,这样其他的事务要想在这个区间插入就会被阻塞,从而保证了幻读不会发生1 4 7 9 15 18
  • 间隔锁只能去锁间隔,而不能锁记录,因此又推出了临键锁。临键锁是间隔所与行锁相结合的产物。在上面的例子中,如果我们查找大于4的所有记录,那么除了(4,7)(7,10)(10,+∞)区间需要加锁以外,7,10记录也需要加锁,都加锁就是临键锁。
  • 不是只要保证不在间隙内部插入数据就可以了吗,为什么还需要锁记录?原因是如果不锁这些在范围内的记录的话,一旦其他的事务修改了这条记录的age,是得它不在这个区间内了,那么也会产生幻读现象

12.乐观锁和悲观锁

  • 悲观锁总是往最坏的情况打算,当一个事务要修改数据时,都要加锁。其他事务阻塞。比如Java中的同步代码块就是应用了悲观锁的原理
  • 乐观锁是假设某一个事务读取数据的时候,都假设他不会修改数据,所以不加锁。只有当这个事务要进行写操作的是时候会判断一些之前有没有人更新过这个数据。实现方式主要有版本号机制,CAS算法
  • 乐观锁适用于读操作比较多的情况,而悲观锁适用于写操作比较频繁的情景。
    在这里插入图片描述

MVCC多版本并发控制

1.好处

  • 在没有MVCC的时候,如果一个事务要访问另一个正在被更新的事务是不可以访问的,因为有排他锁。只有等这个更新的事务提交以后才可以访问相应的记录,导致并发性差。
  • 引入了MVCC以后,即使某一行数据正在被修改,那么其他的读事务也是可以进行访问的,并且不会出现脏读的问题。
    常见的快照读就是MVCC的一个应用

2.快照读和当前读

  • 快照读读取到的可能不是最新的数据,而是之前版本的一个快照。读取的时候不加锁。
  • 当前读读取的时候会给记录加锁,每次读取到的数据一定是最新数据。

3.MVCC实现的基础

  • 隐藏字段(最后一次修改记录的事务ID,指向undo日志的指针)、undoLog、ReadView。

  • 每一条记录除了我们自己写的字段以外,还会有其他的一些隐藏字段,比如记录最后一次修改该记录的事务ID字段,指向undoLog的字段。

  • undoLog。他是一个链表,里面记录了该字段每一次修改后的版本信息。
    在这里插入图片描述

  • 在MVCC机制中,多个事务对同一个行记录进行更新会产生多个历史快照,这些历史快照保存在Undo Log里。如果一个事务想要查询这个行记录,需要读取哪个版本的行记录呢?这时就需要用到ReadView了,它帮我们解决了行的可见性问题。


4.ReadView的结构

  • creator_trx_id,创建这个 Read View 的事务 ID。查询操作默认为0;
  • trx_ids,表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。
  • up_limit_id,活跃的事务中最小的事务 ID。
  • low_limit_id,表示生成ReadView时系统中应该分配给下一个事务的id值。low_limit_id 是系统最大的事务id值,这里要注意是系统中的事务id,需要区别于正在活跃的事务ID。

5.ReadView规则

  • 如果被访问版本的trx_id属性值与ReadView中的creator_trx_id值相同,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
  • 如果被访问版本的trx_id属性值小于ReadView中的up_limit_id值,表明生成该版本的事务在当前事务生成ReadView前已经提交,所以该版本可以被当前事务访问。
  • 如果被访问版本的trx_id属性值大于或等于ReadView中的low_limit_id值,表明生成该版本的事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问。
  • 如果被访问版本的trx_id属性值在ReadView的up_limit_id和low_limit_id之间,那就需要判断一下trx_id属性值是不是在trx_ids列表中。
  • 如果在,说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问。
    如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问。

6.MVCC具体流程

  • 首先获取事务自己的版本号,也就是事务 ID;
  • 生成 ReadView;
  • 查询得到的数据,然后与 ReadView 中的事务版本号进行比较;
  • 如果不符合 ReadView 规则,就需要从 Undo Log 中获取历史快照;
  • 最后返回符合规则的数据。

7.ReadView刷新规则

  • 在读已提交隔离级别下,每一次select都会重新生成一个新的ReadView
  • 在可重复隔离级别下,一个事务中只有第一次select会刷新ReadView

8.MVCC如何解决幻读问题

假设现在查询下面的SQL语句

select * from student where grade > 10

当这条语句执行之前,会生成一个ReadView,然后根据ReadView规则,将数据查询出来。之后事务B又添加了2条符合要求的数据。
再次查询,根据可重复读的规则,ReadView不会再次刷新,实际上查询出来3条记录,然后再根据ReadView规则逐一筛选这3条记录是否符合条件,然后决定是否对该事务可见。从而在可重复读的隔离级别下解决了幻读问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75213.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Editor工具开发实用篇:EditorGUI/EditorGUILayout的区别和EditorGUILayout的方法介绍

目录 一&#xff1a;EditorGUI和EditorGUILayout区别 二&#xff1a;EditorGUILayout 1.EditorGUILayout.BeginFadeGroup(float value); 2.EditorGUILayout.BeginHorizontal EditorGUILayout.BeginVertical 3.EditorGUILayout.BeginScrollView 4.EditorGUILayout.BeginT…

sql-labs-Less1

靶场搭建好了&#xff0c;访问题目路径 http://127.0.0.1/sqli-labs-master/Less-1/ 我最开始在做sql-labs靶场的时候很迷茫&#xff0c;不知道最后到底要得到些什么&#xff0c;而现在我很清楚&#xff0c;sql注入可以获取数据库中的信息&#xff0c;而获取信息就是我们的目标…

概念+示例+横向对比+难点解析征服八大react hooks

8大hooks概念、使用场景 前言 对不同阶段的react开发者会有不同的效果&#xff0c;最终目的是能够对8大react hooks&#xff0c;完全理解&#xff0c;游刃有余。对比useState和useReducer&#xff0c;什么时候使用useMemo和useCallback&#xff0c;useEffect的参数… … use…

文献阅读笔记 # 面向大规模多版本软件系统的代码克隆检测加速技术

面向大规模多版本软件系统的代码克隆检测加速技术&#xff0c;方维康 吴毅坚 赵文耘&#xff0c;《计算机应用与软件》复旦大学软件学院、复旦大学上海市数据科学重点实验室2022 April 面向大规模多版本软件系统的代码克隆检测加速技术 摘要 很多代码克隆检测方法主要针对软…

【博学谷学习记录】超强总结,用心分享丨人工智能 多场景实战 常用英文缩写概念总结

目录PV(Page View)UV(Unique Visitor)CPM(Cost Per Mille)CPC(Cost Per Click)CPA(Cost Per Action)CPI(Cost Per Install)ACU(Average concurrent users)PCU(Peak concurrent users)ARPU(Average Revenue Per User)ARPPU(Average Revenue Per Paying User)LTV(Life Time Value…

Linux命令之lz4命令

一、lz4命令简介 LZ4是一种压缩格式&#xff0c;特点是压缩/解压缩速度超快(压缩率不如gzip)&#xff0c;如果你特别在意压缩速度&#xff0c;或者当前环境的CPU资源紧缺&#xff0c;可以考虑这种格式。lz4是一种非常快速的无损压缩算法&#xff0c;基于字节对齐LZ77系列压缩方…

西电计算机通信与网络(计网)简答题计算题核心考点汇总(期末真题+核心考点)

文章目录前言一、简答计算题真题概览二、网桥&#xff0c;交换机和路由器三、ARQ协议四、曼彻斯特编码和差分曼彻斯特编码五、CRC六、ARP协议七、LAN相关协议计算前言 主要针对西安电子科技大学《计算机通信与网络》的核心考点进行汇总&#xff0c;包含总共26章的核心简答。 【…

【Linux】Linux根文件系统扩容

场景&#xff1a;根文件系统需要至少100GB的剩余空间&#xff0c;但是目前就剩余91GB。因此&#xff0c;我们需要对根文件系统进行扩容。# df -h 文件系统 容量 已用 可用 已用% 挂载点 devtmpfs 3.9G 0 3.9G 0% /dev tmpfs …

密码暴力破解

密码的暴力破解准备工具功能简介Burp Intruder工作原理Intruder应用场景爆破实操准备工具 首先准备好BurpSuite和Dvwa作为测试工具和实验对象。 功能简介 Burp Intruder工作原理 Intruder在原始请求数据的基础上&#xff0c;通过修改各种请求参数&#xff0c;以获取不同的请…

flutter 微信聊天输入框

高仿微信聊天输入框&#xff0c;效果图如下&#xff08;目前都是静态展示&#xff0c;服务还没开始开发&#xff09;&#xff1a; 大家如果观察仔细的话 应该会发现&#xff0c;他输入框下面的高度 刚好就是 软键盘的高度&#xff1b;所以在这里就需要监听软键盘的高度。还要配…

Hbase资源隔离操作指南

1.检查集群的环境配置 1.1 HBase版本号确认> 5.11.0 引入rsgroup的Patch&#xff1a; [HBASE-6721] RegionServer Group based Assignment - ASF JIRA RegionServer Group based Assignment 社区支持版本&#xff1a;2.0.0 引入rsgroup的CDH版本 5.11.0 https://www.…

购买运动耳机应该考虑什么问题、运动达人必备的爆款运动耳机

喜欢运动的小伙伴都知道&#xff0c;运动和音乐是最配的&#xff0c;在运动中伴随着节奏感的音乐能够让自己更兴奋&#xff0c;锻炼的更加起劲儿。在运动耳机方面我也一直都有所研究&#xff0c;购买运动耳机最重要的就是要满足我们运动时候听音乐的需求&#xff0c;从佩戴舒适…

《C++ Primer Plus》(第6版)第5章编程练习

《C Primer Plus》&#xff08;第6版&#xff09;第5章编程练习《C Primer Plus》&#xff08;第6版&#xff09;第5章编程练习1. 计算闭区间内的整数和2. 重新编写程序清单5.43. 累加4. 投资价值5. 销售情况6. 销售情况27. 汽车8. 销售情况29. 销售情况210. 销售情况2《C Prim…

【技术美术图形部分】简述主流及新的抗锯齿技术

电脑的世界里没有曲线&#xff0c;都是三角面组成一个个模型的&#xff0c;因此一定会出现走样&#xff08;锯齿&#xff09;的情况&#xff0c;只是严重与否的问题&#xff0c;而AA也是实时渲染最难解决的问题之一。 Sampling&Artifacts Lecture 06 Rasterization 2 (An…

MAML算法详解(元学习)

文章目录回顾元学习MAML算法MAML和预训练模型的区别数学推导MAML实施细节总结回顾元学习 元学习的基本知识参考这篇博客元学习和机器学习的对比 MAML算法 学习初始化参数&#xff0c;所有任务的初始化的参数都是一样的 MAML和预训练模型的区别 MAML使用的是ϕ\phiϕ…

阶段十:总结专题(第六章:缓存篇)

阶段十&#xff1a;总结专题&#xff08;第六章&#xff1a;缓存篇&#xff09;Day-第六章&#xff1a;缓存篇1. Redis 数据类型**String****List****Hash****Sorted Set**2. keys 命令问题3. 过期 key 的删除策略4. Redis 持久化**AOF 持久化****AOF 重写****RDB 持久化****混…

Python 中 openpyxl 模块封装,读写 Excel 文件中自动化测试用例数据

只有测试数据和错误提示信息不同&#xff0c;其他代码都是一样的&#xff0c;不这样不易修改数据和维护&#xff0c;会有两点痛点 1.代码冗余极其严重, 程序可读性不佳 2.程序拓展性很差 往往我们在自动化测试汇总&#xff0c;会将数据放在 Excel 文件、CSV文件、数据库 Py…

Python-scatter散点图及颜色大全

# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as pltplt.rcParams[font.sans-serif][SimHei] plt.rcParams[axes.unicode_minus] False #matplotlib画图中中文显示会有问题&#xff0c;需要这两行设置默认字体plt.xlabel(X) plt.ylabel(Y) plt.xlim…

【IP技术】ipv4和ipv6是什么?

IPv4和IPv6是两种互联网协议&#xff0c;用于在互联网上标识和寻址设备。IPv4&#xff08;Internet Protocol version 4&#xff09;是互联网协议的第四个版本&#xff0c;是当前广泛使用的互联网协议。IPv4地址由32位二进制数构成&#xff0c;通常表示为4个十进制数&#xff0…

大数据技术之Hive(四)分区表和分桶表、文件格式和压缩

一、分区表和分桶表1.1 分区表partitionhive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录&#xff0c;每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择式选择查询所需要的分区&#xff0c;这样的查询效率辉提高很多。1.1.1 分区表基本语…