Mysql数据库(2)—事务和锁
一、事务
数据库事务的特性?
数据库事务的四大特性是ACID。
- 原子性:就是所有操作要么全不做,要不全做。通过undo日志来实现。
- 一致性:就是在并发情况下数据库由一个状态转移到另一个状态的数据要一致。通过事务的隔离级别来实现。
- 隔离性:多个事务的操作互相不影响,数据有4种隔离级别来解决。基于锁+mvcc机制来实现。
- 持久性:数据库中事务一旦提交,数据持久到硬盘中。基于redo日志来实现。
数据不一致的问题
- 脏读:事务A读取一个数据,事务B对该数据进行修改,修改前后的数据都可以读到,但是数据会不一样,导致了脏读。脏读强调的是读到其他事务未提交的数据。
- 不可重复读:事务A读一个数据,事务B对该数据进行修改后提交,导致事务A前后读取的数据值不一致。不可重复度强调的是读到其他事务提交后的数据和提交前的数据不一致。
- 幻读:事务A读取一个数据,事务B在insert、delete增删记录,事务A两次读取的数据条数不一致;
事务的隔离级别
事务的隔离级别描述的是在多个事务同时运行过程中各自事务中数据的隔离办法,事务的隔离级别是为了解决数据库中以上常见的三类问题,包括:脏读、不可重复读和幻读的问题,者四类隔离级别分别为:
- 未提交读:事务A可以读到事务B未提交的数据;
- 已提交读:事务A只能读到事务B提交后的数据;
- 可重复读:事务A能读取到事务B还未执行完的数据,但是读取到的是事务B未开始事务前的数据,只有当事务B执行完成了才会读取到新的数据;
- 可串形化:事务A、事务B的读写操作是串形化的;
总结:
- 以上4类隔离级别的约束条件从宽松到严格;
- 未提交读隔离级别没有解决任何问题;
- 已提交读解决了脏读的问题;
- 可重复读解决了不可重复读的问题,但还存在幻读的问题,但结合MVCC和record lock能解决幻读的问题;
- 只有可串形化隔离级别能解决所有数据不一致的问题;
- Mysql的默认隔离级别是可重复读。
mysql如何解决幻读?
在快照读情况下,即不加锁的非阻塞读,像普通select操作下通过mvcc避免幻读;通过乐观锁类避免。
对于可重复读的隔离级别下,select * from table的语句是采用快照读的模式,新的事务会读快照;
在当前读情况下,当前读表示需要读取当前最新数据,是加锁的阻塞读写操作,像普通update/insert/delete和加update的select操作,是通过next-key lock避免幻读;通过悲观锁来避免。
对于可重复读的隔离级别,如果是当前读场景,需要通过间隙锁(Gap Lock)模式来避免幻读,这样行间间距会被加锁,不会被新的事务插入新的数据,间隙锁加行锁合起来称为next-key lock;
二、锁
锁是计算机中协调多线程并发访问共享资源的机制,在数据库中就是协调多个事务同时访问同一数据记录的机制,在Mysql数据库中进行加锁的对象是索引中的索引项,会在索引项上做加锁标记。
锁的分类
mysql数据库的锁分为行锁和表锁。

行锁。是innodb存储引擎的默认加锁方式,特点是开销大,加锁慢,锁力度小,所以并发度高,适合写多读少场景。
表锁。是myisam存储引擎的默认加锁方式,特点是开销小,加锁快,锁粒度大,所以并发度低,适合读多写少场景。
记录锁(Record lock):即是行级锁,是innodb存储引擎的默认加锁方式。
间隙锁(Gap lock):会对记录之间的左开右闭的区间进行加锁;
临键锁(Next key Lock):记录锁+间隙锁统称为临键锁。
共享锁(读锁)&独占锁(写锁):共享锁又称S锁/读锁,对记录进行读操作时进行加的锁,可以共享;独占锁又称X锁/写锁,对记录进行写操作时进行加锁,只能独占;
意向共享锁&意向排它锁:为了解决对记录加了共享锁&独占锁,再对表加表锁的时候需要遍历,所以在对行加共享锁&独占锁时候,会对表加上意向共享锁&意向排它锁,下次加表锁一目了然,这是一类表锁。
插入意向锁:就是多个事务在进行插入的时候,已经有事务在进行插入操作了,另一个在等待的事务需要加上插入意向锁,用以表面针对目前的间隙位置有插入的需求;
数据库里的乐观锁和悲观锁?
所有需要加锁的操作都是在进行多线程情况下才需要的。
- 乐观锁比较好理解,就是预测所有线程对数据的操作都是不会冲突的,所以每次对数据进行操作时候都不会加上锁;mysql内部机制可以通过mvcc机制来是实现乐观锁;
- 悲观锁则相反,就是认为每次线程对数据的操作都可能存在冲突,所以需要对数据加上行锁、表锁等。mysql主要通过record lock+nextKey lock来实现。
mysql的悲观锁实现?
mysql加锁是通过锁住索引来实现的,如果没有索引和主键则会锁住整张表。mysql是通过record lock、Gap lock和next-key lock来实现加锁策略的。
- Record lock:对行进行加锁
- Gap lock:对间隙进行加锁
- Next-key lock:Record lock+Gap lock的统称,innodb的默认实现方案;
InnoDB在执行查询语句SELECT时(非串行隔离级别),不会加锁。但是update、insert、delete操作会加行 锁。
mysql默认是autocommit提交事务,如果需要对select语句加锁,需要使用手动设置加锁操作。手动设置加锁的步骤:
begin;
Select * from xxx where xxx for update//加上for update进行强制加写锁;
select * from xxx where xxx lock in share mode//加上lock in share mode进行强制加读锁
进行各种操作//这样的话在还么有commit之前,该行记录一直处于锁定状态;
commit;
mysql的乐观锁mvcc机制原理?
mysql是通过mvcc机制来实现乐观锁的。mvcc是一种不加锁的方式解决读写冲突的机制,支持mysql上了写锁,还能继续支持读,解决读操作阻塞写操作的问题。在mysql中对一行记录的读写,默认使用的是mvcc机制,避免频繁使用加锁机制影响性能。
主要通过隐含字段、undo日志和read view来实现。核心思想是在select查询操作前生成一个read view(一致性读视图)中事务id的大小,用来判断是否需要从undo日志组成的版本链中读取历史数据。
- 隐藏字段:每一条记录都会隐藏row_id、trx_id、roll_ptr。
- undo日志:mysql中的undo日志记录操作前的状态,可以实现回滚到之前状态。
- read view:mysql中存在当前读和快照读的概念,mvcc是通过快照读来实现多线程并发操作的,每次进行读操作时,会生成一个read view,读取之后比较事务id的大小来判断是否进行了一致性读。
mysql本身如何处理死锁问题?
Mysql目前机制是死锁超时会退出,将持有最少行级互斥锁的事务回滚。针对mysql无法自己解决的死锁问题,需要通过线程日志找到发生死锁的线程id,再通过kill 杀掉发生死锁的线程。
如何避免死锁?
问题说明:
两个或多个事务占用同一个共享资源,并且互相请求对方资源的锁,这样就会造成死锁。比如事务A请求事务B加锁的数据,同时事务B请求事务A加锁的数据,这样就会形成死锁情况。
解决方案:
- 让数据的查询尽量索引完成,避免索引加锁失败,从行级锁升级成表锁。
- 保持事务的顺序执行;
- 尽量减少查询范围,避免间隙锁加锁的范围;
- 事务执行逻辑简短,减少加锁时间;
- 死锁检测。执行之前做循环引用的检测。
Mysql只操作一条记录也有可能发生死锁吗?
有可能。Mysql的加锁对象是索引而不是记录,所以当一个事务对该记录的非主键索引加锁,并请求主键索引的锁,但另一个事务对该记录的主键索引已加锁,并请求该记录的非主键索引的锁,那么就会进入死锁状态。
如何优化事务
- 将数据处理工作放在事务外进行,缩短在事务中执行的时间;
- 不要一次性创建逻辑流程太长的事务,将这些事务拆分成多个小事务;
- 事务中不要进行RPC等耗时较长的操作,调用超时可能导致事务超时;
本文由博客一文多发平台 OpenWrite 发布!
相关文章:
Mysql数据库(2)—事务和锁
一、事务 数据库事务的特性? 数据库事务的四大特性是ACID。 原子性:就是所有操作要么全不做,要不全做。通过undo日志来实现。一致性:就是在并发情况下数据库由一个状态转移到另一个状态的数据要一致。通过事务的隔离级别来实现…...
Shell - 加固系统配置
文章目录 #! /bin/bash # Function:对账户的密码的一些加固 read -p "设置密码最多可多少天不修改:" A read -p "设置密码修改之间最小的天数:" B read -p "设置密码最短的长度:" C read -p "设置密码失效…...
【linux】记录archlinux软件包更新后lualatex无法编译的一种解决方案
1 环境参数 操作系统:archlinux Kernel: 6.4.11-arch2-1 包管理器:pacman 日期:2023.08.25 2 问题描述 今天一如往常地进行软件包更新: sudo pacman -Syu随后,在使用luelatex对我的论文(latex)…...
设计模式中的关系
文章目录 一、依赖概念 二,关联概念 三、聚合概念 四、组合概念 五、实现概念 六、继承概念 图总结整体总结 一、依赖 概念 依赖是一种临时使用关系,代码层体现为作为参数。 具体体现:依赖者调用被依赖者的局部变量、参数、静态方法&#…...
C语言之数组题
目录 1.使用函数实现数组操作 2.冒泡排序 3.三子棋 4.【一维数组】交换数组 5.扫雷 6.概念辨析tips 我又来了,今天是数组题,本人还在补军训真的热!🆗 1.使用函数实现数组操作 2.冒泡排序 3.三子棋 4.【一维数组】交换数组 …...
DbContext是Entity Framework中的一个核心类
Entity Framework(简称EF)是ADO.NET的一部分,是一个开源的、通用的对象关系映射(ORM)框架,它使得开发人员可以用面向对象的方式来操作关系数据库。 以下是Entity Framework的一些主要特性: 它…...
BTC价格预测:灰度突如其来的胜利是否会打破“九月魔咒”?
加密市场即将进入第三季度交易的最后阶段,由于9月份被视为是比特币的下跌时期,大多数投资者都预测加密货币之王将会进一步下跌。然而,事情却发生了逆转,灰度突如其来的胜利是否会打破“九月魔咒”? 受该事件影响&#…...
软件测试/测试开发丨Selenium 高级控件交互方法
点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接:https://ceshiren.com/t/topic/27045 一、使用场景 使用场景对应事件复制粘贴键盘事件拖动元素到某个位置鼠标事件鼠标悬停鼠标事件滚动到某个元素滚动事件使用触控笔点击触控笔事件&am…...
算法通关村-----二分查找在二叉搜索树中的应用
二叉搜索树中搜索特定值 问题描述 给定二叉搜索树(BST)的根节点 root 和一个整数值 val。你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。详见leetcode700 代码实现 public TreeNod…...
总结限流、降级与熔断的区别
限流、熔断与降级是流量过大时,通过一定的方式去保护系统的手段,是应对海量流量的三大“杀器”。 限流 限流是从系统的流量入口考虑,从进入的流量上进行限制,通过对并发访问进行限速,达到保护系统的作用。限制并发请求…...
windows下安装go环境 和vscode中go扩展+调试
1. 首先安装GO Go下载地址:go.dev 选择相对应的版本,下载,运行安装程序,并打开命令提示符,运行 go env ,确认已经安装go 注意关注其中GOPATH和GOROOT,这两个地址可以在系统环境变量中进行设置…...
销毁 ECharts 图表
如果想销毁 ECharts 图表,可以使用 dispose 方法。这个方法会销毁图表,并释放所有的资源。 以下是如何使用 dispose 方法的示例: var myChart echarts.init(document.getElementById(main)); // 在需要销毁图表的时候 myChart.dispose(); …...
并发编程的故事——Java线程
Java线程 文章目录 Java线程一、线程创建二、线程运行三、线程运行四、主线程和守护线程五、线程的五种状态六、线程的六种状态七、烧水泡茶案例 一、线程创建 创建线程方法一: Thread重写run方法 Slf4j(topic "c.MyTest1") public class MyTest1 {publ…...
菜鸟教程《Python 3 教程》笔记(13):迭代器与生成器
菜鸟教程《Python 3 教程》笔记(13) 13 迭代器与生成器13.1 迭代器13.1.1 创建一个迭代器13.1.2 StopIteration 13.2 生成器13.3 yield 使用浅析13.3.1 通过 iterable 对象来迭代13.3.2 使用 isgeneratorfunction 判断13.3.3 类的定义和类的实例13.3.4 r…...
ceph架构及 IO流程
CEPH是由多个节点构成的集群,它具有良好的可扩展性和可靠性。节点之间相互通信以达到: 存储和检索数据 数据复制 监控集群的健康状况 保证数据的完整性 检测故障并恢复 基本架构如下图: 分布式对象存储系统RADOS是CEPH最为关键的技术&a…...
ssh 基本用法与免密登录
基本用法 远程连接服务器: ssh userhostname user:用户名hostname:IP地址或域名 举个例子,假设我们的user是tom,hostname是123.45.67.890 可以输入:ssh tom123.45.67.890 第一次登陆时会提示:…...
Unity3D 如何在ECS架构下,用Unity引擎进行游戏开发详解
前言 Unity3D是一款强大的游戏引擎,它提供了丰富的功能和工具,可以帮助开发者快速构建高质量的游戏。而Entity Component System(ECS)是Unity3D中一种新的架构模式,它可以提高游戏的性能和可扩展性。本文将详细介绍在…...
Kotlin协程flow的debounce与管道Channel
Kotlin协程flow的debounce与管道Channel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutines.runBlockingco…...
在JavaScript中,你可以使用多种方法来查找包含特定元素的数组或对象
1、indexOf():这个方法返回元素在数组中首次出现的位置。如果没有找到元素,则返回-1。 let array [1, 2, 3, 4, 5]; console.log(array.indexOf(3)); // 输出: 2 console.log(array.indexOf(6)); // 输出: -12、includes():这个方法检查数…...
实力认证!OceanBase获“鼎信杯”优秀技术支撑奖
6 月 30 日,2023 “鼎信杯”信息技术发展论坛在京隆重举办第二届“鼎信杯”大赛颁奖典礼。OceanBase 凭借完全自主研发的原生分布式数据库,以及丰富的核心系统国产数据库升级案例,斩获“优秀技术支撑奖”。 论坛上,国内首个基于在…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
