iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >数据库之锁模块
  • 159
分享到

数据库之锁模块

2024-04-02 19:04:59 159人浏览 泡泡鱼
摘要

MyISAM与InnoDB关于锁方面的区别 MyISAM与InnoDB关于锁方面的区别: MyISAM默认使用的是表级锁,不支持行级锁 InnoDB默认用的是行级锁,也支持表级锁 InnoDB支持事务,在

MyISAM与InnoDB关于方面的区别

MyISAM与InnoDB关于锁方面的区别:

  • MyISAM默认使用的是表级锁,不支持行级锁
  • InnoDB默认用的是行级锁,也支持表级锁
  • InnoDB支持事务,在事务中被加锁的数据行需要 等事务commit之后才会统一解锁,否则不会解锁。而MyISAM不支持事务,所以不会有这个问题
  • MyISAM和InnoDB都支持共享锁和排他锁,读锁共享,写锁排他
  • InnoDB在开启事务时,若select语句不走索引的情况会锁住整张表,也就是说InnoDB在sql没有利用到索引的时候使用的是表级锁,而SQL用到索引的时候则是使用行级锁和gap锁,gap锁是走普通非唯一索引时用到的
  • InnoDB除了支持行级锁之外,还支持表级的意向锁,意向锁分为共享读锁(IS)和排他写锁(IX)

注:

实际上在不走索引的时候,InnoDB的实现方式和MyIsam的表锁方式不同,单条索引记录上加锁,record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁(排他锁),此时想改变树型结构即索引结构的话,是会被锁住的,这个类似于表锁,但原理上和表锁是完全不同的

MyISAM适合的场景:

  • 频繁执行全表count语句
  • 对数据进行增删改的频率不高,而查询非常频繁的场景
  • 没有事务场景

InnoDB适合的场景:

  • 数据进行增删改查都相当频繁的系统
  • 可靠性要求比较高,需要事务特性的系统

数据库锁的分类:

  • 按锁的粒度划分,可分为表级锁、行级锁、页级锁
  • 按锁级别划分,可分为共享锁、排他锁
  • 按加锁方式划分,可分为自动锁、显式锁
  • 按操作划分,可分为DML锁、DDL锁
  • 按使用方式划分,可分为乐观锁、悲观锁;悲观锁通常需要利用数据库提供的锁机制来实现;而乐观锁通常用版本号或时间戳来实现

总结:

MyISAM默认使用的是表级锁,不支持行级锁。InnoDB默认用的是行级锁,也支持表级锁。无论是表级锁还是行级锁,均分为共享锁和排他锁,它们的关系如下表所示(X:排他锁,S:共享锁):
数据库之锁模块


事务隔离级别以及各级别下的并发访问问题以及事务隔离机制

事务并发访问引起的问题以及如何避免:

1.更新丢失:

即一个事务的更新覆盖了另一个事务的更新;由于现在主流数据库都会自动加锁来避免更新丢失的情况,所以在数据库层面通常不会发生这个问题。例如Mysql所有事务隔离级别在数据库层面上均可避免更新丢失

下图模拟了更新丢失的过程:
数据库之锁模块

2.脏读(Dirty read):

即一个事务读到另一个事务的未提交数据;该问题在READ-COMMITTED(读已提交)以上的事务隔离级别可避免

3.不可重复读(Non-repeatable read):

即事务A多次读取同一数据,但事务B在事务A多次读取的过程中对该数据做了更新操作并提交,导致事务A多次读取同一数据时结果不一致;该问题在REPEATABLE-READ(可重复读)以上的事务隔离级别可避免,这也是mysql的默认隔离级别

4.幻读(Phantom read):

事务A读取以搜索条件相匹配的若干行数据,而事务B则对事务A查询匹配的数据进行了插入或删除操作,导致事务A多次读取的结果集行数不一致;该问题在SERIALIZABLE(串行化)以上的事务隔离级别可避免,需要注意的是:在MySQL数据库中,REPEATABLE-READ事务隔离级别下也可以避免幻读

总结
数据库之锁模块


当前读和快照读

表象:快照读(非阻塞读)-- 伪mvcC(多版本并发控制)
内在:next-key锁(行级锁+gap锁)

首先我们需要知道两个概念:当前读和快照读;当前读其实就是加了锁的增删改查语句,例:

  • select ... lock in share mode;select ... for update
  • update,delete,insert(自动加锁)

之所以叫当前读,是因为读取的是当前记录的最新版本,而RR事务隔离级别下在读取数据之后还需要保证其他事务不能修改当前记录,那么就会对读取的记录加next-key锁,所以RR事务隔离级别下的当前读可以避免发生幻读现象:
数据库之锁模块

快照读则是不加锁的非阻塞读,例如不加锁的普通select操作。但需要注意的是在串行化的事务隔离级别下,任何的增删改查操作都会被加锁。

在mysql中,读已提交隔离级别下,快照读和当前读都是读到同样的数据。而在可重复读隔离级别下,快照读读到的是开启事务时第一条select语句读到的快照版本数据,当前读则是会读到当前数据库中最新的数据。

RC、RR级别下的InnoDB的快照读(非阻塞读)是如何实现的:

  • 一是依靠数据行里的隐藏字段:DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID字段
    • DB_TRX_ID:最后修改本行数据的事务id
    • DB_ROLL_PTR:回滚指针,指向undo日志的历史版本数据
    • DB_ROW_ID:行号,即密集索引维护的自增id
  • 二是undo日志,当我们对数据进行变更操作时就会产生undo日志,undo日志中存储的是历史数据,当一个旧事务需要读取数据时,会顺着undo链找到满足其可见性的数据;undo日志还分为insert undo日志和update undo日志
    • insert undo日志:记录insert操作产生的undo日志,该日志记录只在事务回滚时需要,而在事务提交后会立即丢弃
    • update undo日志:记录update或delete操作产生的undo日志,该日志记录不仅在事务回滚时需要,快照读也需要,所以不会马上被删除,只有当数据库所使用的快照中不涉及该日志记录才会被删除
  • 三是read view,它主要用来做可见性判断的,即当我们去执行快照读时,会针对我们查询的数据创建一个read view,以此来决定该事务能看到的是哪个版本的数据。read view的创建时机是开启事务后执行的第一条select语句
    • read view遵循一个可见性算法,该算法会先取出将要变更数据行的DB_TRX_ID,与系统其他活跃的事务id做对比,如果大于等于这些活跃的事务id就会通过DB_ROLL_PTR去undo日志里取出DB_TRX_ID小于当前活跃事务id的历史数据

事务对行的更新过程:
数据库之锁模块
数据库之锁模块


RR事务隔离级别下是如何避免幻读的

在之前的小节中,我们了解到在MySQL的RR事务隔离级别下,是可以避免幻读的。但并不意味着快照读是避免发生幻读现象的根本,因为快照读只是读的发生变化前的历史数据。实际在RR及SERIALIZABLE事务隔离级别下真正防止幻读发生的原因是事务对数据加上了next-key锁,而next-key锁由行锁和gap锁两部分组成。行锁就不多说了,gap锁才是重点,所谓gap就是索引树中插入新记录的间隙,而gap锁是用于锁定一个间隙范围但不包括记录本身,gap锁的目的是为了防止同一事务的两次当前读而导致出现幻读的情况。

gap锁只在RR和SERIALIZABLE事务隔离级别中存在,其他的隔离级别是没有的,所以RC和RU是无法避免幻读的。这里我们主要讨论RR事务隔离级别下gap锁出现的场景:

  • 增删改查及当前读若用到主键索引或唯一索引会对其加gap锁吗?
    • 答:视情况而定,如果where条件全部命中,则不会用gap锁,只会加行锁;而where条件部分命中或者全不命中,则会加gap锁;所以gap锁会用在非唯一索引或者不走索引的当前读中

where条件全部命中,只会加行锁:
数据库之锁模块

走非唯一索引时会对该索引间隙加gap锁:
数据库之锁模块

不走索引则会对表里所有的间隙加gap锁,其效果就类似于表级锁了,但是其代价比表级锁更大:
数据库之锁模块

总结:

无论是当前读还是快照读,在innodb的RR的事务隔离级别下都可以避免幻读。在快照读的情况下,innodb通过mvcc来避免幻读;在当前读的情况下,innodb通过next-key锁来避免幻读。

您可能感兴趣的文档:

--结束END--

本文标题: 数据库之锁模块

本文链接: https://www.lsjlt.com/news/45861.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 数据库之锁模块
    MyISAM与InnoDB关于锁方面的区别 MyISAM与InnoDB关于锁方面的区别: MyISAM默认使用的是表级锁,不支持行级锁 InnoDB默认用的是行级锁,也支持表级锁 InnoDB支持事务,在...
    99+
    2022-10-18
  • 数据库之索引模块
    索引模块除了是数据库最重要的模块之一,也是面试中最经常被问到的,关于索引模块常见问题如下: 为什么要使用索引 什么样的信息能成为索引 索引的数据结构 密集索引和稀疏索引的区别 为什么要使用索引: 数据...
    99+
    2022-10-18
  • 数据库锁之乐观锁
    一、乐观锁的介绍   乐观锁是相对悲观锁而言,也是为了避免数据库幻读、业务处理时间过长等原因引起数据处理错误的一种机制,但乐观锁不会刻意使用数据库本身的锁机制,而是依据数据本身来保证数据...
    99+
    2022-10-18
  • 【Python】系列模块之pymysql操作MySQL 数据库
    目录 一、安装pymysql 二、连接数据库 三、数据库操作 3.1 查询 3.2 更新 3.3 使用循环批量更新  Python 系列文章学习记录:  Python系列之Windows环境安装配置_开着拖拉机回家的博客-CSDN博客 ...
    99+
    2023-09-03
    数据库 python mysql pymysql
  • 数据分析之pandas模块
          一、Series   类似于一位数组的对象,第一个参数为数据,第二个参数为索引(索引可以不指定,就默认用隐式索引) Series(data=np.random.randint(1,50,(10,))) Series(data...
    99+
    2023-01-30
    模块 数据 pandas
  • 十二、Python高级功能之Mysql数据库模块
    Python高级功能之Mysql数据库模块安装python mysql组件# yum -y install MySQL-python.x86_64以下根据实例来说明:>>> import ...
    99+
    2022-10-18
  • oracle数据库事务transaction锁lock模式思考之一
    前言         数据库事务是oracle非常基础又极为重要的概念。之前已经介绍过相关的一些概念,相关文章见下:      o...
    99+
    2022-10-18
  • Python中的pandas表格模块、文件模块和数据库模块
    目录一、Series数据结构1、Series的创建2、Series属性2、Series缺失数据处理二、DataFrame数据结构1、DataFrame的创建2、DataFrame属性...
    99+
    2022-11-11
  • Python数据序列化之pickle模块
    目录1将Python数据存储为本地文件①存储过程②加载过程2将Python数据存储为程序的一部分①存储过程②加载过程前言: 在英语中 pickle 名词是泡菜,动词是腌渍的意思。可以...
    99+
    2022-11-13
  • Python 安装mysql数据库模块
    方法一:命令行安装mysql模块 先找到Python安装目录下的Script文件 当前路径下进入cmd命令窗口,输入pip3 install pymysql  3.如上图所示就是安装成功  方法二:PyCharm下安装...
    99+
    2023-09-09
    数据库 python mysql
  • 【python】之serial模块,读写串口数据!
    串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。串口是计算机上一种非常通用的设备通信协议。pyserial模...
    99+
    2023-09-13
    python pip
  • Python之数组模块——array
    该模块定义了一个对象类型,可以表示一个基本值的数组:整数、浮点数、字符。 数组模块array的大部分属性及方法的应用: import array #array.array(typecode,[initializer])——typeco...
    99+
    2023-01-31
    数组 模块 Python
  • 调用pymysql模块操作数据库
    1、创建数据库表: 1 def create_table(tb_name): 2 import pymysql#导入模块 3 #连接数据库 4 db = pymysql.Connect('localhos...
    99+
    2023-01-31
    模块 操作 数据库
  • 详解Python常用标准库之os模块与shutil模块
    目录系统模块常用方法常用属性文件操作路径模块文件复制移动模块(文件操作)copyfileobj -- 复制文件(内容)copyfile -- 复制文件(内容)copymode -- ...
    99+
    2022-11-11
  • MySQLdb模块如何操作MySQL数据库
    下面一起来了解下MySQLdb模块如何操作MySQL数据库,相信大家看完肯定会受益匪浅,文字在精不在多,希望MySQLdb模块如何操作MySQL数据库这篇短内容是你想要的。1. python连接mysql的...
    99+
    2022-10-18
  • Python使用FlaskMigrate模块迁移数据库
    目录前言安装初始化项目结构三大命令前言 本篇文章,阐述一下Flask中数据库的迁移 为什么要说数据库迁移呢? 比如我们以前有一个数据库,里面的信息有 id, name现在我想再加一个...
    99+
    2022-11-11
  • 3Python标准库系列之os模块
    This module provides a portable way of using operating system dependent functionality. If you just want to read or write...
    99+
    2023-01-31
    模块 标准 系列之
  • 【2020Python修炼记】MySQL之 数据备份、pymysql模块
    【目录】 一、IDE工具介绍与安装使用——navicat 神器 二、MySQL数据备份 三、pymysql模块 安装 使用模块 一、IDE工具介绍与安装使用——navicat 神器 https://www.cnblogs.co...
    99+
    2018-05-23
    【2020Python修炼记】MySQL之 数据备份 pymysql模块
  • Node.js处理I/O数据之使用Buffer模块缓冲数据
    一、前传 在之前做web时也经常用到js对象转json和json转js对象.既然是Node.js处理I/O数据,也把这个记下来。 Json转Js对象:JSON.parse(jsons...
    99+
    2022-11-13
  • 数据库锁表和解锁
    问题描述 在开发或生产环境中,我们经常会遇到数据库锁表的情况,一旦发生锁表,对业务将会产生很大的影响,本篇主要介绍如何判断数据库锁表和锁表后的处理。 mysql锁表处理 一、导致锁表的原因 锁表发生在insert update 、...
    99+
    2023-08-20
    数据库 mysql java sql oracle
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作