(新手友好)MySQL学习笔记(完):事务和锁

事务和锁

事务

transaction,一组原子性的SQL查询,或者说是一个独立的工作单元。如果能够成功执行这组查询的全部语句,就会执行这组查询;如果其中任何一条语句无法成功执行,那么这组查询的所有语句都不会执行。

也就是说,事务内部的语句,要么全部执行成功,要么全部执行失败。

使用事务

  • 开始标志:任何一条DML语句的执行
  • 结束标志:
    • 提交:成功的结束,将所有的DML语句操作记录和底层硬盘文件中数据进行同步
    • 回滚:失败的结束:将所有DML语句操作记录全部清除

MySQL默认是自动提交

#开启事务
start transaction;
#提交事务
commit;
#保存回滚点
savepoint 回滚点名;
#回滚事务
rollback[to 回滚点名];#查看事务的提交方式
show variables like 'autocommit';
#启用和关闭自动提交模式
set autocommit = 1;
set autocommit = 0;

举例:转账业务

  • 创建表并插入数据
drop table if exists account;
create table account(id int primary key auto_increment,name varchar(20),money int check(money >= 0)
);
insert into account(name,money
)
values
('张三',20000),
('李四',500);
  • 自动提交和手动提交,再开一个MySQL—Front窗口查看数据变化

事务的四个特性(ACID)

ACID:

  • A(原子性 atomicity):事物是最小工作单元,不可再分,一个事务的所有操作要么全部执行成功,要么执行失败全部回滚,不会出现成功一部分的情况
  • C(一致性 consisyency):数据库总会从一个一致的状态转变成另一个一致的状态,不会因为一条语句的失败而出现另外的状态,打个比方事物执行成功前的状态是 0 ,执行成功后的状态是 1,不会因为某一条语句的失败而出现 0.5的状态。
  • I(隔离性 isolation):通常来说,一个事物所做的修改在最终提交前,对于其他事物是不可见的,即在最终提交前该事务的修改不会影响到其他事务。
  • D(持久性 durability):事务一旦提交,其做的修改会持久的保存到数据库中,即使系统崩溃,修改的数据也不会丢失。

一个兼容ACID的数据库系统很多复杂但可能用户并没有察觉到的工作.相比没有实现ACID的数据库,通常回需要更强的CPU处理能力,更大的内存和更多的磁盘空间。

持久性原理:

一般事务的持久性都是借助redo log来实现的。

Redo log(重做日志)是一种日志文件,记录了对于数据库的修改操作(包括插入,修改删除等等操作),它的主要作用就是确保系统或数据库崩溃之后,系统能够通过重做日志上记录的操作,从而是数据库回到事务提交后的状态,确保事务的持久性。

并行事务带来的问题

数据一致性问题:

  • 脏读(dirty read):一个事务读到另一个事务未提交的数据就是脏读,因为一个事务对于一条记录做修改,在该事务未提交前所做的修改随时有可能回滚,因此被另一个事务读到并回滚的数据就是脏数据。
  • 不可重复读(non-repeatable read):在一个事务内多次读取同一条记录,前后结果不一致就是不可重复读,比如事务A多次查询同一行数据,在某次查询间隔中,事务B对该行数据进行了修改并提交,导致事务A对该行数据的下次读取出现了不一致,这种情况就叫不可重复读。
  • 幻读(phantom read):在一个事务内按照相同的条件多次查询,前后结果集的数量不同就是幻读,比如事务A按照id>5的条件进行多次查询,出现幻读前的查询结果一直是count(*)=3,在某次查询间隔中,事务B插入了一条id=9的数据并提交,那么在修改后事务A查询到的结果就会变成count(*)=4,这就是幻读问题。

注意:不可重复读主要针对数据本身,幻读则针对的是查询读取的结果集数量。

影响:

  • 脏读:读到其他事务未提交的数据
  • 不可重复读:前后读取的数据不一致
  • 幻读:前后读取的结果集数量不同

隔离级别

在SQL标准中定义了四个隔离级别,每一种级别都规定了一个事务中所做的修改,哪些事物内和事务间是可见的,哪些是不可见的。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

  • 未提交读(READ UNCOMMITED):事务中未提交的修改也可以被其他事务读取到,这个隔离等级会出现包括脏读,不可重复读,幻读问题,一般不用。
  • 提交读(READ COMMITED):事务中的修改在提交之后才会被其它事务读取到,这样就避免了脏读问题,但是还是会出现不可重复读和幻读问题。
  • 可重复读(REPEATABLE READ):同一事物中多次读取同样记录的结果是一致的,就解决的脏读和不可重复读的问题,但是幻读问题还是未得到完全的解决,值得注意的一点是隔离级别是MySQL的默认隔离级别,又因为MySQL的特质该隔离级别可以解决大部分幻读问题。
  • 串行化(SERIALIZABLE):强制事务串行执行,不会出现并行事务,所以就解决了脏读,不可重复读,幻读的问题,该隔离等级会读取的行上添加行锁以及隔离锁以避免幻读问题,同时对于读取操作加入共享锁,写入操作加入排他锁,值得一提的串行化虽然能够避免所有有关一致性的问题,但是因为它并发性能低,容易死锁,效率低,在一般项目中很少用,更多的还是使用可重复读或提交读。

查看隔离级别:

#查看会话级的当前隔离级别:(会话级只对当前窗口有效)
select @@tx_isolation
select @@session.tx_isolation
#查看全局级的当前隔离级别:
select @@global.tx_isolation

设置隔离级别:

  • 方法1:my.ini文件中的[mysqld]下面添加transaction-isolation =隔离级别
  • 方法2:通过指令
#设置全局或当前会话范围
set global transaction isolation level 隔离级别;
set session transaction isolation level 隔离级别;

实现隔离级别的两种方法:

  • 加锁:读数据前对其,阻止其他事务对数据修改
  • 快照:读取数据的快照(之前的版本)实现,例如,可重复读级别在整个事务期间都读取事务开始时的快照去解决不可重复读问题。

InnoDB中的锁

共享锁和排他锁

  • 共享锁(S Lock):读锁,允许事务读取数据
  • 排他锁(X Lock):也叫独占锁,写锁,允许事务删除或更新数据

如果事务获取了某个数据的共享锁,其他事务可以立即获取该数据的共享锁,这种情况叫锁兼容。如果事务获取了某个数据的共享锁或排他锁,其他事务想要获取该数据的排他锁,必须要等到该行的锁被释放掉。

排他锁和共享锁的兼容性

意向锁

InnoDB允许事务在行锁和表锁同时存在。为支持在不同粒度上进行加锁,InnoDB支持意向锁。

意向锁,将锁定的对象分为多个层级,意向锁意味着事务有意向在更细粒度上加锁。如果需要加锁,需要先对表意向锁再对加行锁。

意向锁在InnoDB中就是表级别的锁,支持两种意向锁:

  • 意向共享锁(IS Lock),事务有意向对表中某些行加共享锁
  • 意向排他锁(IX Lock),事务有意向对表中某些行加排他锁

表级锁的兼容性

注意:意向锁不会和行级锁冲突,意向锁之间也不会冲突,意向锁只会和共享表锁和排他表锁冲突

意向锁的作用:如果没有意向锁,想要给一个表加表锁必须要检查该表是否有表锁和每一行是否有锁。而如果在加行锁前给这个表加上了意向锁,这时只需要检查表锁和意向锁就可以了,不需要检查每一行锁。

一致性非锁定读

一致性非锁定读,读取正在执行delete和update操作的行时,不会等待该行上锁的释放,而是读取该行的一个快照数据(该行之前的版本)。非锁定读极大的提高了数据库的并发性,InnoDB默认时这种读取方式,也就是说默认普通的select语句不会加锁而是通过读取快照实现数据一致性。

上面提到的快照数据就是该行数据的历史版本,由此带来的并发控制称为多版本并发控制(MVCC)。

READ COMMITTED(提交读)和REPEATABLE READ(可重复读)在InnoDB中使用的是一致性非锁定读,但是读取的快照不同。提交读级别读取的是最新版本的快照,可重复读级别读取的是事务开始时数据的快照。

可重复读级别通过读快照,可以解决前面提到的幻读问题,但是有些情况需要锁定读。

一致性锁定读

InnoDB默认使用一致性非锁定读。某些情况用户需要显示加锁保证数据的一致性,支持两种一致性锁定读的操作。

  • select ... for update:对读取的行加一个排他锁
  • select ... lock in share mode:对读取的行加一个共享锁

如果只对读取的行加锁会有幻读问题:

锁定读时使用键值间隙锁(Next-Key Lock),就是行锁加间歇锁,来解决幻读问题。

  • Record Lock:单行记录的锁,比如只锁3这行记录
  • Gap Lock:间歇锁,锁定一个范围,但不包括记录本身就像这样只锁(1-2)(4-5)个范围的记录
  • Next-Key Lock:Record Lock+Gap Lock,锁定一个范围,并锁定记录本身两个相加就成了锁定(1-5)所有的记录

非锁定读使用快照和锁定读使用间歇锁可以基本解决幻读问题,但是极特殊情况还是有可能发生幻读。

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

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

相关文章

【CMake】使用 CMake 将单模块 C 项目构建为库并链接主程序

目录1. 项目结构设计📦 结构说明2. 项目文件内容2.1 顶层 CMakeLists.txt2.2 模块 src/color/CMakeLists.txt ✅【推荐写法】❓是否需要写 project()?2.3 模块头文件 include/color.h2.4 模块实现文件 src/color/color.c2.5 主程序 src/main.c3. 构建与运…

从零开始的云计算生活——番外4,使用 Keepalived 实现 MySQL 高可用

目录 前言 一、架构原理​ ​Keepalived 作用​ ​MySQL 主从复制​ 二、环境准备​ 服务器要求​: 安装基础软件​ 三、配置 MySQL 主从复制 四、配置 Keepalived 主节点配置​(/etc/keepalived/keepalived.conf) 从节点配置 五、…

list类的常用接口实现及迭代器

目录 1. list类的介绍 2.list类的常用接口 2.1 list类的常用构造 2.2 list类对象的容量操作 2.3 list迭代器 2.4 list类的常用操作 3.list的模拟实现 1. list类的介绍 list代表的是双向链表,常见的有创建,增,删,改几个接口…

vscode Cline接入火山引擎的Deepseek R1

创建火山引擎Deepseek R1的API 在火山引擎管理控制台中创建Deepseek R1推理接入点(大模型),创建成功后会看到下图效果。在操作中选择API调用,在页面中选择OpenAI SDK,按照步骤找到baseUrl地址和API_KEY,后续…

新手向:自动化图片格式转换工具

大家好!今天我要分享一个非常实用的Python小工具——图片格式批量转换器。如果你经常需要处理大量不同格式的图片文件,或者需要统一图片格式以便于管理,那么这个工具将会成为你的得力助手!一、为什么需要图片格式转换?…

CUDA中的内存管理、锁页内存、UVA统一虚拟地址、零拷贝、统一内存

文章目录0 前言1 swap内存跟锁页内存2 UVA(Unified Virtual Addressing)统一虚拟地址3 先看最普通的cuda内存分配、释放、传输4 申请锁页内存4.1 cudaHostAllocDefault4.2 cudaHostAllocPortable4.3 cudaHostAllocWriteCombined4.3 cudaHostAllocMapped4.4 几种锁页内存总结4.5…

微服务环境下的灰度发布与金丝雀发布实战经验分享

微服务环境下的灰度发布与金丝雀发布实战经验分享 在大规模微服务架构中,如何平滑安全地上线新功能是每个后端团队的痛点。本文将结合生产环境中的真实案例,分享灰度发布(Gray Release)与金丝雀发布(Canary Release&am…

MEF 在 WPF 中的简单应用

MEF核心笔记MEF 的开发模式主要适用于插件化的业务场景中,C/S 和 B/S 中都有相应的使用场景,其中包括但不限于 ASP.NET MVC 、ASP WebForms、WPF、UWP 等开发框架。当然,DotNet Core 也是支持的。 以下是搜索到一些比较好的博文供参考&#…

Gitlab跑CICD的时候,maven镜像和pom.xml使用的maven版本冲突导致没办法build成功的解决方法

是这样的!最近遇到一个非常棘手的难题,我搞了大概2周时间才把他弄出来,因为自己搭了个私服的maven仓库,他不像maven官方仓库一样,可以跟nginx一样转的,所以遇到好几个难点!第一点:就…

Linux内核IPv4路由查找:LPC-Trie算法的深度实践

在互联网基础设施的核心领域,路由查找性能直接决定了网络转发效率。Linux内核作为现代网络系统的基石,其IPv4路由子系统采用了一种名为LPC-Trie(Level-Compressed Trie) 的创新数据结构,在net/ipv4/fib_trie.c文件中实现了高效的路由管理方案。本文将深入剖析这一机制的设…

【设计模式】装饰(器)模式 透明装饰模式与半透明装饰模式

装饰模式(Decorator Pattern)详解一、装饰模式简介 装饰模式(Decorator Pattern) 是一种 结构型设计模式,它允许你动态地给对象添加行为或职责,而无需修改其源代码,也不需要使用继承来扩展功能。…

NAT原理与实验指南:网络地址转换技术解析与实践

NAT实验 NAT(Network Address Translation,网络地址转换): NAT技术的介绍: 随着Internet用户的快速增长,以及地址分配不均等因素,IPv4地址(约40亿的空间地址)已经陷入不…

设计模式之【观察者模式】

目录 观察者模式中的角色 通过一个简单案例来演示观察者模式 被观察者接口 事件类型 up主类作为被观察者 观察者接口 粉丝类作为观察者 测试 测试结果 观察者模式中的角色 被观察者(observable)观察者(observer) 通过一个简单案例来演示观察者模式 被观察者接口 /*…

Linux sudo host权限提升漏洞(CVE-2025-32462)复现与原理分析

免责声明 本文所述漏洞复现方法仅供安全研究及授权测试使用; 任何个人/组织须在合法合规前提下实施,严禁用于非法目的; 作者不对任何滥用行为及后果负责,如发现新漏洞请及时联系厂商并遵循漏洞披露规则。 漏洞简述 Linux sudo是l…

【uni-ui】hbuilderx的uniapp 配置 -小程序左滑出现删除等功能

1.网址:https://ext.dcloud.net.cn/plugin?id181](https://ext.dcloud.net.cn/plugin?id181) 2.csdn讲解:https://blog.csdn.net/qq_40323256/article/details/114337128 3.uni-ui git:https://github.com/dcloudio/uni-ui 4.官方网址文档&…

记一次POST请求中URL中文参数乱码问题的解决方案

POST请求中URL中文参数乱码前言:一个常见的开发痛点一、问题现象与原因深度解析1. 典型问题场景2. 根本原因分析URL编码规范问题:编码解码过程不一致:IE浏览器特殊行为:二、前端解决方案1. 手动编码URL参数(推荐&#…

从存储热迁移流程了解 QEMU block layer

文章目录存储热迁移流程总体流程代码路径QEMU Block layer架构简述Block Job结构体设计状态转换Mirror block job拓扑结构构建过程数据结构存储热迁移流程 总体流程 Libvirt migrate 命令提供 copy-storage-all 选项支持存储热迁移,相应地,Libvirt 热迁…

【设计模式】命令模式 (动作(Action)模式或事务(Transaction)模式)宏命令

命令模式(Command Pattern)详解一、命令模式简介 命令模式(Command Pattern) 是一种 行为型设计模式(对象行为型模式),它将一个请求封装为一个对象,从而使你可以用不同的请求对客户进…

HTML5智能排班日历:动态排班一目了然

这个日历将具备以下功能: 显示一个标准的月度日历视图。可以自由切换上一个月和下一个月。在日历的每一天自动显示当天值班的人员。您可以很方便地在文件中修改值班人员列表和排班的起始日期。包括:动态生成日历网格处理月份切换根据排班规则计算并显示每天的值班人员<!DO…

深度剖析C++生态系统:一门老牌语言如何在开源浪潮中焕发新生?

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、前言&#xff1a;C的“长寿秘诀”是什么&#xff1f; C 诞生已超过 40 年。它经历了桌面应用、互联网爆发、移动时代&#xff0c;再…