MySQL高级(五):事务

概念

事务是数据库管理系统中用于保证数据一致性和完整性的重要机制。它允许将一组操作视为一个整体,要么全部执行,要么全部回滚,以确保数据的正确性。

事务的特性(ACID)

原子性(Atomicity)

  • 整个事务是不可分割的操作单元,要么全部成功执行,要么失败后回滚。
  • 例如:转账中,A账户扣款和B账户入账必须同时成功,否则事务回滚。

一致性(Consistency)

  • 事务执行前后,数据库必须保持一致性状态。
  • 例如:银行总余额在转账操作后保持不变。

隔离性(Isolation)

  • 一个事务的执行不应影响其他事务,即使它们同时操作相同的数据。
  • MySQL 提供不同的隔离级别(见后续内容)。

持久性(Durability)

  • 一旦事务提交,其对数据库的修改应永久保存,即使系统发生崩溃。

事务相关操作

基本命令

  • 启动事务
START TRANSACTION;
  • 提交事务
COMMIT;
  • 回滚事务
ROLLBACK;
  • 查看当前隔离级别
SELECT @@transaction_isolation;
  • 设置事务隔离级别
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

自动提交模式

  • 默认情况下,MySQL 是 自动提交模式
    每个 SQL 语句执行后都会自动提交。

  • 关闭自动提交:

SET AUTOCOMMIT = 0;

事务隔离级别

MySQL 提供四种隔离级别,用于处理并发事务中的数据一致性问题。

隔离级别描述可能出现的问题
READ UNCOMMITTED可以读取未提交的数据(脏读)。脏读、不可重复读、幻读
READ COMMITTED只能读取其他事务已提交的数据。不可重复读、幻读
REPEATABLE READ保证在一个事务内多次读取相同的数据结果一致(MySQL 默认)。幻读
SERIALIZABLE强制事务串行执行,避免所有并发问题,但性能较低。

事务的具体案例

案例 1:银行转账

假设有一个账户表 accounts,包含以下字段:

  • account_id: 账户 ID
  • balance: 账户余额

需求:从账户 A 转账 100 元到账户 B。

-- 假设账户 A 的 ID 是 1,账户 B 的 ID 是 2
START TRANSACTION;-- 从账户 A 扣除 100 元
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;-- 向账户 B 添加 100 元
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;-- 检查账户 A 的余额是否小于 0
SELECT balance FROM accounts WHERE account_id = 1;-- 如果余额小于 0,回滚事务
IF (balance < 0) THENROLLBACK;
ELSECOMMIT;
END IF;

案例 2:库存管理

假设有一个订单系统,涉及以下两个表:

  • products:记录商品库存;
  • orders:记录订单信息。

需求:下单时,检查库存是否充足,如果不足则回滚事务。

-- 假设商品 ID 是 101,用户购买了 2 件商品
START TRANSACTION;-- 检查库存是否足够
SELECT stock FROM products WHERE product_id = 101;-- 假设检查的库存数量保存在变量 @stock
IF (@stock < 2) THENROLLBACK; -- 库存不足,回滚
ELSE-- 扣减库存UPDATE products SET stock = stock - 2 WHERE product_id = 101;-- 插入订单记录INSERT INTO orders (product_id, quantity) VALUES (101, 2);-- 提交事务COMMIT;
END IF;

事务的常见问题

  1. 死锁问题
    • 当两个事务互相等待对方释放资源时,会发生死锁。
    • MySQL 会自动检测死锁,并回滚其中一个事务。
  2. 长事务
    • 长时间运行的事务可能锁定资源,影响系统性能。
    • 优化方法:
      • 尽量缩短事务的生命周期。
      • 提交或回滚后立即释放锁。
  3. 锁的粒度
    • InnoDB 支持行级锁,但在某些情况下会升级为表锁(如未使用索引的查询)。
  4. 读写分离
    • 在高并发场景下,可以通过主从复制实现读写分离,提升性能。

事务优化

在 MySQL 中,优化事务的使用对提高性能和减少资源占用至关重要。以下是 MySQL 事务优化的一些常见方法和策略:

1. 减少事务的生命周期

  • 尽量缩短事务的执行时间
    • 确保事务内的逻辑尽量简单,避免不必要的计算或等待操作。
    • 在事务中尽量避免用户交互或外部依赖(如网络调用),以减少事务锁的持有时间。
  • 提前准备数据
    • 在开始事务之前,准备好所需的查询条件和数据,减少事务内的操作时间。
  • 及时提交或回滚事务
    • 当事务完成或检测到错误时,立即执行 COMMITROLLBACK 以释放资源。

2. 减少锁的粒度

  • 使用合适的索引
    • 确保 WHERE 条件中的列有索引,以减少锁定的行数。
    • 避免全表扫描,减少锁从行级锁升级为表锁的风险。
  • 控制事务锁的范围
    • 只操作必要的行或表,避免不必要的锁定。
  • 分批操作
    • 对大批量数据的修改操作,可以分批次执行,减少单个事务中的锁资源占用。

3. 选择合适的事务隔离级别

  • 不同的隔离级别对事务性能和一致性要求有不同的影响:
    • READ COMMITTEDREPEATABLE READ 是较常用的隔离级别,通常能在一致性和性能之间取得平衡。
    • SERIALIZABLE 隔离级别提供最高的数据一致性,但性能开销最大,应尽量避免在高并发场景中使用。
    • 根据业务需求,选择最合适的隔离级别,避免不必要的性能损耗。

4. 减少并发事务冲突

  • 读写分离
    • 使用主从复制将读操作分流到从库,减少主库的写入压力。
    • 确保事务中的写操作只发生在主库。
  • 分区表设计
    • 将数据分布在多个分区中,减少并发事务对同一表的争用。
  • 避免热点更新
    • 在高并发场景中,减少对同一行或少数行频繁更新的情况。

5. 避免死锁

  • 固定资源访问顺序
    • 在事务中以固定的顺序访问表或行,减少死锁发生的概率。
  • 分解长事务
    • 将一个长事务拆分成多个短事务,避免长时间锁定资源。
  • 及时处理冲突
    • 捕获死锁异常,并重新尝试事务逻辑。

6. 使用批量操作

  • 批量插入、更新、删除

    • 避免逐条执行操作,尽可能使用批量语句提高效率,例如:

      INSERT INTO table_name (col1, col2) VALUES (1, 2), (3, 4), (5, 6);
      
  • 分块提交

    • 对于需要修改大量数据的事务,将其拆分成多个小事务,以减轻单次事务的压力。

7. 合理配置 MySQL 参数

  • innodb_lock_wait_timeout

    • 设置事务等待锁的超时时间,避免事务长时间占用资源。

      SET innodb_lock_wait_timeout = 50;
      
  • innodb_flush_log_at_trx_commit

    • 配置日志刷新策略,可以平衡性能和数据持久性:
      • 值为 1(默认值):事务提交时强制刷盘,保证持久性。
      • 值为 2:减少刷盘频率,性能更高但持久性稍弱。
  • innodb_buffer_pool_size

    • 提高 InnoDB 缓冲池大小,以减少磁盘 IO,提高性能。
  • binlog_format

    • 选择合适的二进制日志格式(STATEMENTROWMIXED),根据事务内容优化日志性能。

8. 避免不必要的事务

  • 对于只读操作,不需要使用事务。例如:

    SELECT ...;
    
  • 对于非关键性数据写入,可以采用异步写入或消息队列来减少事务压力。

9. 使用更高效的 SQL 语句

  • 避免 SELECT FOR UPDATE 误用
    • 只在确实需要锁定行时使用 SELECT FOR UPDATE,否则使用普通的 SELECT
  • 优化 DML 语句
    • 确保 UPDATEDELETE 的条件明确,减少无效锁。

10. 监控和调试事务性能

  • 使用性能工具
    • 使用 MySQL 提供的性能工具(如 SHOW ENGINE INNODB STATUS)来检查事务锁和死锁信息。
  • 启用慢查询日志
    • 检查长时间运行的事务,并针对这些事务进行优化。
  • 分析事务的行锁等待
    • 通过 INFORMATION_SCHEMA.INNODB_LOCKSINNODB_LOCK_WAITS 查看锁冲突信息。

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

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

相关文章

数据结构之二:表

顺序表代码&#xff1a;SData/SqList/SeqList.h Hera_Yc/bit_C_学习 - 码云 - 开源中国 链表相关代码&#xff1a;SData/ListLink/main.c Hera_Yc/bit_C_学习 - 码云 - 开源中国 本文主要讲解的是线性表&#xff08;逻辑线性&#xff09;&#xff0c;对于非线性表不做补充。…

《Python基础》之循环结构

目录 简介 一、for循环 1、基本语法与作用 2、使用 range() 函数配合 for 循环 3、嵌套的for循环 二、while循环 1、基本语法与作用 2、while 循环嵌套 &#xff08;1&#xff09;、while循环与while循环嵌套 &#xff08;2&#xff09;、while循环与for循环嵌套 简介 …

基于LiteFlow的风控系统指标版本控制

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 更新日志 最近关于https://github.com/wnhyang/coolGuard此项目更新了如下内容&#xff1a;https://g…

Mysql中的 TEXT 和 BLOB 解析

&#x1f680; 博主介绍&#xff1a;大家好&#xff0c;我是无休居士&#xff01;一枚任职于一线Top3互联网大厂的Java开发工程师&#xff01; &#x1f680; &#x1f31f; 在这里&#xff0c;你将找到通往Java技术大门的钥匙。作为一个爱敲代码技术人&#xff0c;我不仅热衷…

241124_文本解码原理

241124_文本解码原理 一个文本序列的概率分布可以分解为每个词基于其上文的条件概率的乘积。 Greedy search 就是每步都选择概率最大的&#xff0c;不会去考虑全局 按照贪心搜索输出the nice woman 的概率就是0.5*0.40.2 这种方法简单&#xff0c;但也存在问题&#xff0c;比…

介绍一下strlwr(arr);(c基础)

hi , I am 36 适合对象c语言初学者 strlwr(arr)&#xff1b;函数是把arr数组变为小写字母 格式 #include<string.h> strlwr(arr); 返回值为arr 链接分享一下arr的意义(c基础)(必看)(牢记)-CSDN博客 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #incl…

16:(标准库)ADC三:使用外部触发启动ADC/模拟看门狗

使用外部触发启动ADC 1、外部中断线EXTI11触发ADC2、外部定时器TIM2_CH2触发ADC3、ADC中模拟看门狗的使用 1、外部中断线EXTI11触发ADC ADC的触发方式有很多&#xff0c;一般情况都是使用软件触发反式启动ADC转换。除了软件触发方式还能使用外部事件触发启动ADC转换。如下图所…

Linux之管道,system V的共享内存,消息队列和信号量

Linux之管道&#xff0c;systemV共享内存和信号量 一.进程间通信1.1进程间通信的目的1.2进程间通信的方式 二.管道2.1管道的概念2.2匿名管道2.3命名管道 三.system V3.1共享内存3.2消息队列3.3信号量 一.进程间通信 在我们之前有关Linux指令的学习时我们使用过“|”这个命令&a…

使用ChatGPT生成和优化电子商务用户需求规格说明书

在电子商务项目开发中&#xff0c;用户需求规格说明书&#xff08;User Requirement Specification, URS&#xff09;是团队沟通与项目成功的基石。然而&#xff0c;面对复杂多变的需求&#xff0c;如何快速生成清晰、完整且具备说服力的文档&#xff1f;这正是AI工具的用武之地…

1+X应急响应(网络)常见网络攻击-SQL注入:

常见网络攻击-SQL注入&#xff1a; SQL注入概述&#xff1a; 动态网站的工作流程&#xff1a; SQL注入的起源&#xff1a; SQL典型的攻击手段&#xff1a; SQL注入的危害&#xff1a; SQL注入的函数&#xff1a; SQL注入类型&#xff1a; 提交方式分类&#xff1a; Get注入&am…

Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图

用户打开 PDF 文档时&#xff0c;他们会看到 PDF 的初始视图。默认情况下&#xff0c;打开 PDF 时不会显示书签面板或缩略图面板。在本文中&#xff0c;我们将演示如何设置文档属性&#xff0c;以便每次启动文件时都会打开书签面板或缩略图面板。 Spire.PDF for .NET 是一款独…

[Docker-显示所有容器IP] 显示docker-compose.yml中所有容器IP的方法

本文由Markdown语法编辑器编辑完成。 1. 需求背景: 最近在启动一个服务时&#xff0c;突然发现它的一个接口&#xff0c;被另一个服务ip频繁的请求。 按理说&#xff0c;之前设置的是&#xff0c;每隔1分钟请求一次接口。但从日志来看&#xff0c;则是1秒钟请求一次&#xff…

单片机GPIO的8种工作模式

1、输入 GPIO_MODE_AIN:模拟输入 GPIO_MODE_IN_FLOATING:浮空输入 GPIO_MODE_IPD:下拉输入 GPIO_MODE_IPU:上拉输入 2、输出 GPIO_MODE_OUT_OD:开漏输出&#xff08;特殊情况使用&#xff09; GPIO_MODE_OUT_PP&#xff1a;推挽输出-----点灯&#xff08;通用&#…

Azkaban部署

首先我们需要现在相关的组件&#xff0c;在这里已经给大家准备好了相关的安装包&#xff0c;有需要的可以自行下载。 只需要启动hadoop集群就可以&#xff0c;如果现在你的hive是打开的&#xff0c;那么请你关闭&#xff01;&#xff01;&#xff01; 如果不关会造成证书冲突…

时钟使能、

时钟使能 如果正确使用&#xff0c;时钟使能能够显著地降低系统功耗&#xff0c;同时对面积或性能的影响极小。但是如果不正确地使用时钟使能&#xff0c; 可能会造成下列后果&#xff1a; • 面积增大 • 密度减小 • 功耗上升 • 性能下降 在许多使用大量控制集的…

视觉经典神经网络与复现:深入解析与实践指南

目录 引言 经典视觉神经网络模型详解 1. LeNet-5&#xff1a;卷积神经网络的先驱 LeNet-5的关键特点&#xff1a; 2. AlexNet&#xff1a;深度学习的突破 AlexNet的关键特点&#xff1a; 3. VGGNet&#xff1a;深度与简洁的平衡 VGGNet的关键特点&#xff1a; 4. ResNe…

【CSS in Depth 2 精译_060】9.3 详解 CSS 作用域的相关概念、最新 @scope 规则的应用及注意事项

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 【第九章 CSS 的模块化与作用域】 ✔️ 9.1 模块的定义 9.1.1 模块和全局样式9.1.2 一个简单的 CSS 模块9.1.3 模块的变体9.1.4 多元素模块 9.2 将模块组合为更大的结构 9.2.1 模块中多个职责的拆分…

uniapp实现开发遇到过的问题(持续更新中....)

1. 在ios模拟器上会出现底部留白的情况 解决方案&#xff1a; 在manifest.json文件&#xff0c;找到开源码视图配置&#xff0c;添加如下&#xff1a; "app-plus" : {"safearea":{"bottom":{"offset" : "none" // 底部安…

React(六)——Redux

文章目录 项目地址基本理解一、配置Redux store二、创建slice配置到store里并使用三、给Slice配置reducers&#xff0c;用来修改初始值 项目地址 教程作者&#xff1a;教程地址&#xff1a; 代码仓库地址&#xff1a; 所用到的框架和插件&#xff1a; dbt airflow基本理解 s…

国家级资质!同驭汽车获得CNAS实验室认证

近日&#xff0c;同驭汽车科技顺利通过中国合格评定国家认可委员会&#xff08;简称CNAS&#xff09;评审&#xff0c;获得《中国合格评定国家认可委员会实验室认可证书》。这标志着同驭已建立国际标准的实验室管理体系&#xff0c;产品的试验与检测技术能力达到了国际认可的准…