MySQL学习之事务,锁机制

事务

什么是事务?

事务就是逻辑上的一组操作,要么全做,要么全不做

事务经典例子:转账,转账需要两个操作,从一个人账户上减钱,在另一个账户上加钱,比如说小红给小明转账100元,就需要先从小红账上-100,再去小明账上+100,这两个操作要么都做要么都不做,要是只做一个操作,就会出现问题。保证两个操作都做的就是事务

事务的四大特性:

原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;

一致性: 执行事务后,数据库从一个正确的状态变化到另一个正确的状态;

隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;

持久性:一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

并发导致的问题:

脏读:当一个事务正在访问数据并且对数据进行了修改,而这种修改还没提交到数据库中,这时候的另一个事务也访问了这个数据,然后使用了数据,因为这个数据是还没有提交的数据,那么另一个数据读取到的就是“脏数据”,依据“脏数据”做出的操作可能是不正确的

幻读:它发生在一个事务(事务1)读取了几行数据,紧接着另一个并发的事务(事务2)插入了一条数据,在事务1随后的查询过程中就会发现一些原本不存在的记录,好像发生了幻觉一样,所以称之为幻读。

不可重复读: 指的是事务1在本事务内多次去读同一数据,在这个事务还没结束时,事务2对该数据进行了访问并修改,由于数据发生了修改,那么第一个事务在两次读取数据之间就有可能造成不一样,这就发生了一个事务连续两次读到的数据不一样的情况,称之为不可重复读。

丢失修改: 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。

为了解决以上出现的问题:

事务提出了四个隔离级别

SQL 标准定义了四个隔离级别:

  • READ-UNCOMMITTED(读取未提交):

最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

  • READ-COMMITTED(读取已提交):

允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

  • REPEATABLE-READ(可重复读):

对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

  • SERIALIZABLE(可串行化):

最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

隔离级别

脏读

不可重复读

幻读

READ-UNCOMMITTED

READ-COMMITTED

×

REPEATABLE-READ

×

×

SERIALIZABLE

×

×

×

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)

锁机制与InnoDB锁算法

MyISAM和InnoDB存储引擎使用的锁:

  • MyISAM采用表级锁(table-level locking)。
  • InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁

表级锁和行级锁对比:

  • 表级锁: MySQL中锁定 粒度最大 的一种锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。其锁定粒度最大,触发锁冲突的概率最高,并发度最低,MyISAM和 InnoDB引擎都支持表级锁。
  • 行级锁:MySQL中锁定 粒度最小 的一种锁,只针对当前操作的行进行加锁。 行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。

Record Lock: 单个行记录上的锁

Gap Lock: 间隙锁,锁定一个范围,不包括记录本身

Next-key Lock: record+gap 锁定一个范围,包含记录本身

虽然使用行级索具有粒度小、并发度高等特点,但是表级锁有时候也是非常必要的:

  • 事务更新大表中的大部分数据直接使用表级锁效率更高;
  • 事务比较复杂,使用行级索很可能引起死锁导致回滚。

 锁分类

共享锁(S锁):

如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不 能加排他锁。获取共享锁的事务只能读数据,不能修改数据。

排他锁(X锁):

如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获取排他锁的事务既能读数据,又能修改数据。

死锁和避免死锁

不同于MyISAM总是一次性获得所需的全部锁,InnoDB的锁是逐步获得的,当两个事务都需要获得对方持有的锁,导致双方都在等待,这就产生了死锁。 发生死锁后,InnoDB一般都可以检测到,并使一个事务释放锁回退,另一个则可以获取锁完成事务,我们可以采取以上方式避免死锁:

  • 通过表级锁来减少死锁产生的概率;
  • 多个程序尽量约定以相同的顺序访问表(这也是解决并发理论中哲学家就餐问题的一种思路);
  • 同一个事务尽可能做到一次锁定所需要的所有资源。

相关知识点:

  1. innodb对于行的查询使用next-key lock
  2. Next-locking keying为了解决Phantom Problem幻读问题
  3. 当查询的索引含有唯一属性时,将next-key lock降级为record key
  4. Gap锁设计的目的是为了阻止多个事务将记录插入到同一范围内,而这会导致幻读问题的产生
  5. 有两种方式显式关闭gap锁:(除了外键约束和唯一性检查外,其余情况仅使用record lock) A. 将事务隔离级别设置为RC B. 将参数innodb_locks_unsafe_for_binlog设置为1

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

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

相关文章

JAVA在线文档

1.存在码 JDK21中文API 2.全栈行动派 JDK17中文API 3.mklab.cn JDK11中文API JDK8中文API JDK7-21英文API 4.docs.oracle.com JDK7-22英文文档

项目笔记| 基于Arduino和IR2101的无刷直流电机控制器

本文介绍如何使用 Arduino UNO 板构建无传感器无刷直流 (BLDC) 电机控制器或简单的 ESC(电子速度控制器)。 无刷直流电机有两种类型:有传感器和无传感器。有感无刷直流电机内置3个霍尔效应传感器,这些传感…

MLIR的TOY教程学习笔记

MLIR TOY Language 文章目录 MLIR TOY Language如何编译该项目ch1: MLIR 前端IR解析ch2: 定义方言和算子 (ODS)1. 定义方言2. 定义OP3. OP相关操作4. 定义OP ODS (Operation Definition Specification)1. 基本定义2. 添加文档3. 验证OP4. 新增构造函数5. 定义打印OP的格式 ch3:…

【机器学习】超参数选择:解锁机器学习模型潜力的关键

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 超参数选择:解锁机器学习模型潜力的关键引言什么是超参数&#xff1…

计算机的错误计算(三十八)

摘要 计算机的错误计算(十九)指出:两个等价大数相减,差不是正确值0,而是一个大数。本节用 Python的 torch库中函数进行计算验证,进一步说明错误的一般性。 例1. 在Windows10,Python 3.12.4 下…

Android APP Camerax应用(02)预览流程

说明:camera子系统 系列文章针对Android12.0系统,主要针对 camerax API框架进行解读。 1 CameraX简介 1.1 CameraX 预览流程简要解读 CameraX 是 Android 上的一个 Jetpack 支持库,它提供了一套统一的 API 来处理相机功能,无论 …

【HarmonyOS NEXT】网络请求 - 分页加载

分页加载关键字:onReachEnd 一、申请网络权限 在 module.json5 文件中,添加网络权限: {"module": {..."requestPermissions": [{"name": "ohos.permission.INTERNET","usedScene": {&qu…

网络安全常用易混术语定义与解读(Top 20)

没有网络安全就没有国家安全,网络安全已成为每个人都重视的话题。随着技术的飞速发展,各种网络攻击手段层出不穷,保护个人和企业的信息安全显得尤为重要。然而,在这个复杂的领域中,许多专业术语往往让人感到困惑。为了…

portainer教程-docker可视化管理工具

很多朋友刚接触docker 学习,就想问 docker有图形化界面吗 ,答案是肯定的, 这里白眉大叔 给大家推荐 Docker可视化管理平台 -- Portainer 1- 运行Portainer: docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restarta…

【保姆级讲解C语言中的运算符的优先级!】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 🪶C语言中的运算符的优先级 🪶C语言中的运算符的优先级决定了…

二、C#数据类型

本文是网页版《C# 12.0 本质论》第二章解读。欲完整跟踪本系列文章,请关注并订阅我的Essential C# 12.0解读专栏。 前言 数据类型(Data Type)是一个很恼人的话题。 似乎根本没必要对数据类型进行展开讲解,因为人人都懂。 但是…

16、基于共享内存二叉树的LRU

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 在共享内存的二叉树上尝试了LR…

grafana大坑,es找不到时间戳 | No date field named timestamp found

grafana大坑,es找不到时间戳。最近我这边的es重新装了一遍,结果发现grafana连不上elasticsearch了(以下简称es),排查问题查了好久一直以为是es没有装成功或者两边的版本不兼容,最后才发现是数值类型问题 一…

XSLFO 文档:格式化 XML 数据的艺术

XSLFO 文档:格式化 XML 数据的艺术 1. 引言 XSLFO(Extensible Stylesheet Language Formatting Objects)是一种基于 XML 的语言,用于描述如何将 XML 数据格式化为可视化的文档,如 PDF 或打印的页面。XSLFO 提供了一种…

过滤器、同步异步、跨域问题、json数据格式字符串

1、过滤器 过滤器是将JavaEE中对请求和响应进行拦截的技术,定义一个类实现Filter接口,可以让某些请求地址在到达servlet之前进入到指定的过滤器中从而实现统一管理,例如编码过滤,权限过滤等进行统一过滤。 下面是一个编码过滤的…

Java 基础语法教程

1. 类和对象 Java 是一种面向对象的编程语言,它使用类和对象来组织代码。一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。 1.1 类 类(Class)是一个模板,它描述一类对象的行为和…

浅聊 Three.js 屏幕空间反射SSR-SSRShader

浅聊 Three.js 屏幕空间反射SSR(2)-SSRShader 前置基础 渲染管线中的相机和屏幕示意图 -Z (相机朝向的方向)||| -------------- <- 屏幕/投影平面| | || | || | (f) | <- 焦距| | ||…

在 Ubuntu 22.04/20.04 安装 CVAT 和 SAM 指南

1. 安装 Docker 和 Docker Compose sudo apt-get update sudo apt-get --no-install-recommends install -y \apt-transport-https \ca-certificates \curl \gnupg-agent \software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-ke…

跨平台游戏引擎 Axmol-2.1.4 发布

2.1.4 版本是用于错误修复和改进的次要 LTS 版本&#xff0c;感谢 axmol 的所有贡献者 相对于 2.1.3 的重大变化&#xff1a; 添加 JobSystem 支持添加 cmake 选项 AX_WASM_INITIAL_MEMORY添加 Linux WebView 实现改进 curl 下载实现 使用curl_multi_poll代替select使用curl_…

java-如何打破双亲委派机制

在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;双亲委派模型是一种类加载器之间的层次模型&#xff0c;它定义了类加载的规则&#xff0c;即当一个类需要被加载时&#xff0c;JVM默认的行为是首先请求父类加载器加载该类&#xff0c;只有当父类加载器无法加载该类时&a…