当前位置: 首页 > web >正文

11.MySQL事务管理详解

MySQL事务管理详解

文章目录

MySQL事务管理
事务的概念
事务的版本支持
事务的提交方式
事务的相关演示
事务的隔离级别
查看与设置隔离级别
读未提交(Read Uncommitted)
读提交(Read Committed)
可重复读(Repeatable Read)
串行化(Serializable)
隔离级别总结
关于一致性
多版本并发控制
记录中的3个隐藏字段
undo日志
快照的概念
Read View
RR与RC的本质区别


MySQL事务管理

事务的概念

事务是数据库操作的基本单位,由一条或多条SQL语句组成。这些语句在逻辑上紧密关联,共同完成一个特定任务。比如银行转账场景:从A账户扣除金额、向B账户增加金额,这两个操作必须同时成功或失败,否则就会出现数据不一致的问题。

事务的核心特性是ACID:

  • 原子性(Atomicity):事务内的操作要么全部完成,要么全部不完成。如果中间某个步骤失败,整个事务会回滚到初始状态。
  • 一致性(Consistency):事务执行前后,数据库的完整性约束(如主键、外键)必须保持有效。
  • 隔离性(Isolation):多个事务并发执行时,彼此之间互不干扰,避免数据混乱。
  • 持久性(Durability):一旦事务提交,对数据的修改就是永久的,即使系统崩溃也不会丢失。

为什么需要事务?试想如果没有事务,当执行到转账的第二步时服务器突然宕机,A账户的钱被扣了但B账户没收到,这会导致严重的资金错误。事务的出现就是为了简化开发者的编程模型,让数据库自动处理这些复杂场景。

事务的版本支持

MySQL的事务支持依赖于存储引擎。通过SHOW ENGINES命令可以看到不同引擎的特性:

mysql> SHOW ENGINES;
+--------------------+---------+--------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                          | Transactions | XA   | Savepoints |
+--------------------+---------+--------------------------------------------------+--------------+------+------------+
| InnoDB             | DEFAULT | Supports transactions, row-level locking, etc. | YES          | YES  | YES        |
| MyISAM             | YES     | MyISAM storage engine                          | NO           | NO   | NO         |
+--------------------+---------+--------------------------------------------------+--------------+------+------------+

关键字段解读

  • Transactions:是否支持事务。InnoDB支持,而MyISAM不支持。
  • XA:是否支持分布式事务(跨多个数据库的事务)。
  • Savepoints:是否支持保存点(事务内可回滚到某个中间状态)。

因此,如果需要事务功能,必须选择InnoDB引擎。这也是MySQL默认使用InnoDB的原因之一。

事务的提交方式

事务的提交分为两种模式:

  1. 自动提交(Auto-commit):每条SQL语句单独作为一个事务,执行完立即提交。
  2. 手动提交(Manual commit):通过BEGINSTART TRANSACTION显式开启事务,直到执行COMMITROLLBACK才会结束。

查看当前提交模式

mysql> SHOW VARIABLES LIKE 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+

切换提交模式

SET autocommit = 0; -- 关闭自动提交(手动模式)
SET autocommit = 1; -- 开启自动提交(默认模式)

手动事务示例

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- 或 ROLLBACK;

如果在执行过程中发生错误(如网络中断),未提交的事务会自动回滚,确保数据安全。

事务的相关演示

准备测试表

创建一个银行用户表:

CREATE TABLE bank_users (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50),balance DECIMAL(10,2)
);

插入初始数据:

INSERT INTO bank_users (name, balance) VALUES ('张三', 1000);
演示一:事务的常规操作
  1. 开启事务

    START TRANSACTION;
    
  2. 插入数据

    INSERT INTO bank_users (name, balance) VALUES ('李四', 500);
    
  3. 查看未提交的数据
    在另一个终端执行:

    SELECT * FROM bank_users; -- 可能看不到李四的记录(取决于隔离级别)
    
  4. 回滚操作

    ROLLBACK;
    
  5. 验证数据回滚

    SELECT * FROM bank_users; -- 李四的记录消失
    
演示二:原子性

假设事务中执行两条SQL:

START TRANSACTION;
UPDATE bank_users SET balance = balance - 1000 WHERE id = 1; -- 超出余额
UPDATE bank_users SET balance = balance + 1000 WHERE id = 2;
COMMIT;

如果第一条SQL导致余额为负数(违反业务规则),整个事务会回滚,确保数据一致性。

演示三:持久性

提交后的事务即使遇到服务器宕机,数据也不会丢失。例如:

START TRANSACTION;
UPDATE bank_users SET balance = balance + 100 WHERE id = 1;
COMMIT; -- 数据持久化到磁盘

事务的隔离级别

四种隔离级别对比
隔离级别脏读不可重复读幻读加锁读
读未提交(Read Uncommitted)
读已提交(Read Committed)
可重复读(Repeatable Read)
串行化(Serializable)

选择建议

  • 读未提交:几乎不用,数据混乱。
  • 读已提交:Oracle默认级别,适合对一致性要求不高的场景。
  • 可重复读:MySQL默认级别,平衡性能与一致性。
  • 串行化:极端场景使用,性能差。
查看与设置隔离级别

查看全局/会话隔离级别

SELECT @@global.tx_isolation; -- 全局
SELECT @@session.tx_isolation; -- 当前会话

设置隔离级别

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

多版本并发控制(MVCC)

记录中的3个隐藏字段

InnoDB的每条记录包含以下隐藏字段:

  • DB_TRX_ID:6字节,最近修改该记录的事务ID。
  • DB_ROW_ID:6字节,隐式自增主键。
  • DB_ROLL_PTR:7字节,回滚指针,指向undo日志中的历史版本。

示例:插入一条记录后:

INSERT INTO students (name, age) VALUES ('王五', 20);

该记录的DB_TRX_ID为当前事务ID,DB_ROLL_PTRNULL(无历史版本)。

undo日志

undo日志用于事务回滚和MVCC。当事务修改数据时:

  1. 先将旧版本拷贝到undo log。
  2. 更新记录的DB_TRX_IDDB_ROLL_PTR
  3. 提交后释放锁。

版本链形成:每次修改都会生成新版本,通过DB_ROLL_PTR串联成链表。

Read View

Read View是事务进行快照读时生成的可见性视图,包含:

  • m_ids:活跃事务ID列表。
  • m_up_limit_id:最小活跃事务ID。
  • m_low_limit_id:下一个待分配的事务ID。
  • m_creator_trx_id:创建该View的事务ID。

可见性判断规则

  1. 事务ID < m_up_limit_id:可见。
  2. 事务ID >= m_low_limit_id:不可见。
  3. 事务ID在两者之间且不在m_ids中:可见。
RR与RC的本质区别
  • RR(可重复读):事务第一次快照读生成Read View,后续读复用该View,保证多次读取结果一致。
  • RC(读已提交):每次快照读生成新的Read View,因此可能读到其他事务已提交的修改。

示例

  1. 事务A修改数据并提交。
  2. 事务B在事务A提交前进行快照读,则RR下看不到修改,RC下能看到。

关于一致性

一致性是事务的最终目标,依赖原子性、隔离性和持久性共同保障。例如转账场景中:

  • 原子性确保要么全部成功,要么全部失败。
  • 隔离性防止其他事务看到中间状态(如A扣款后B未到账)。
  • 持久性保证提交后数据永久保存。

如果业务逻辑存在漏洞(如未检查余额),一致性仍会被破坏,因此开发者需自行验证业务规则。


隔离级别总结

隔离级别性能安全性适用场景
读未提交无需准确性,如统计分析
读已提交中高一般业务,如订单查询
可重复读核心业务,如银行交易
串行化最高极端场景,如库存扣减

选择时需权衡性能与安全性,大多数场景推荐使用可重复读。

http://www.xdnf.cn/news/12225.html

相关文章:

  • 十八、【用户认证篇】安全第一步:基于 JWT 的前后端分离认证方案
  • 物流瘫痪预警:亚马逊多仓爆仓,卖家如何抢占夏季性价比市场?
  • 【Android基础回顾】五:AMS(Activity Manager Service)
  • 【Java Web】9.Maven高级
  • AI编程助手入门指南:GitHub Copilot、Cursor与Claude的安装与基础使用
  • [ Qt ] | 与系统相关的操作(三):QFile介绍和使用
  • 零碳园区:多维构建绿色标杆,开启美丽中国新纪元
  • 抑郁症患者数据分析
  • Redis大量key集中过期怎么办
  • 环境变量深度解析:从配置到内核的全链路指南
  • DAY 22 Kaggle 比赛
  • 简化复杂系统的优雅之道:深入解析 Java 外观模式
  • 无人机军用与民用技术对比分析
  • C++自定义简单的内存池
  • 数据分析实战2(Tableau)
  • 极昆仑HybridRAG方案:突破原生 RAG 瓶颈,开启大模型应用新境界
  • 企业管理中,商业智能BI主要做哪些事情?
  • 优化学习笔记
  • 网络安全面试题目(无答案)
  • OrCAD X Capture CIS设计小诀窍系列第二季--03.如何在Capture中输出带有目录和元器件信息的PDF
  • 数数科技正式加入上海市人工智能协会,共筑DATA×AI新基建
  • 全球IP归属地查询接口如何用C#进行调用?
  • Dify应用类型和工作流介绍
  • Postgresql源码(146)二进制文件格式分析
  • 贪心,回溯,动态规划
  • 打通印染车间“神经末梢”:DeviceNet转Ethernet/IP连接机器人的高效方案
  • 03 Deep learning神经网络的编程基础 代价函数(Cost function)--吴恩达
  • Mysql锁及其分类
  • Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
  • 使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第十五讲)