Mysql:事务管理(上)

在数据库的操作中,我们最常用的就是增删改查(CURD)。但在多用户并发的场景下,如果简单的CURD不加控制,会发生什么?

想象一个火车站售票系统

  • 当前票数: 1张。

  • 客户端A: 检查发现还有1张票,准备下单。

  • 客户端B: 在同一时刻也检查了票数,发现还有1张,也准备下单。

  • 结果: A和B都买到了票,数据库票数变成-1。这就是典型的"超卖"问题。

为了解决这类并发导致的数据不一致问题,MySQL引入了------事务(Transaction)


一、 什么是事务?

事务是一组DML(数据操作语言)语句的集合。在逻辑上,这些语句具有强相关性。

事务内的SQL语句要么全部执行成功,要么全部执行失败。

事务有两种类型:

1)当 autocommit = ON, 一个单独的SQL语句就是一个事务

比如select *from Roles;

2)由begin开始,commit结束

begin;

savepoint s1;

...

savepoint s2;

...

rollback;

commit;

二、 事务的核心特性:ACID原则

一个完整的事务必须满足四个属性,简称ACID

1. 原子性(Atomicity)
  • 定义: 事务是不可分割的最小工作单元。

  • 核心逻辑: 事务中的所有操作要么全部完成,要么全部不完成。

  • 实现机制: 如果在执行过程中发生错误,数据库会进行回滚(Rollback),将数据恢复到事务开始前的状态,仿佛这个事务从未发生过一样。

2. 一致性(Consistency)
  • 定义: 事务执行前后,数据库的完整性没有被破坏。

  • 核心逻辑: 写入的数据必须完全符合所有的预设规则(如约束、触发器等)。一致性其实是原子性、隔离性和持久性共同追求的最终目标

3. 隔离性(Isolation)
  • 定义: 数据库允许多个并发事务同时对数据进行读写。隔离性可以防止多个事务交叉执行时导致数据不一致。

  • 隔离级别: 为了平衡性能与安全,MySQL提供了四种隔离级别:

    • 读未提交(Read Uncommitted)

    • 读提交(Read Committed)------大部分数据库默认级别

    • 可重复读(Repeatable Read)------ MySQL默认级别

    • 串行化(Serializable)

4. 持久性(Durability)
  • 定义: 事务处理结束后,对数据的修改就是永久性的。

  • 核心逻辑: 一旦事务提交,即使系统发生故障(如断电、宕机),修改过的数据也不会丢失,会被刷新到磁盘中。

三、 事务的版本支持

需要注意的是,并不是所有的MySQL存储引擎都支持事务。

  • InnoDB: 支持事务,是目前最常用的默认引擎。

  • MyISAM: 不支持事务。

四、 事务的提交方式与基本操作

MySQL默认是**自动提交(autocommit)**的。即每执行一条DML语句,MySQL就会自动帮你执行一次 COMMIT。

核心操作指令:

  • 开启事务: BEGIN 或 START TRANSACTION;

  • 设置保存点: SAVEPOINT 点名称; (就像单机游戏的"存盘点")

  • 回滚到保存点: ROLLBACK TO 点名称;

  • 全部回滚: ROLLBACK; (彻底撤销本次事务所有操作)

  • 提交事务: COMMIT; (正式将改动持久化到磁盘)

五、 并发带来的三个"典型问题"

在多事务并发执行时,如果不进行隔离,会产生以下三种现象:

  1. 脏读(Dirty Read): 事务A读到了事务B尚未提交的数据。如果事务B最后回滚了,A读到的就是无效的"脏数据"。

  2. 不可重复读(Non-repeatable Read): 事务A在同一个事务内多次读取同一条数据 ,结果却不一样 (因为期间事务B修改并提交了该数据)。

  3. 幻读(Phantom Read): 事务A在同一个事务内多次按某个条件查询,结果发现记录数变多了(因为期间事务B插入并提交了新记录)。

知晓了这三个问题,我们来看看四大隔离级别。


六、四大隔离级别(读-写)

为了解决上述问题,SQL标准定义了四种隔离级别。MySQL通过这些级别,在"性能"与"安全性"之间寻求平衡。

**数据库并发的场景有三种:**读-读,读-写,写-写

1.读-读:不存在任何问题,也不需要并发控制
2.读-写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读

3.写-写 :有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失(后面补充)

这里先用读-写场景来介绍四种隔离级别。

1. 读未提交(Read Uncommitted)

特点: 最低级别,没有任何隔离性。

现象: 会产生脏读、不可重复读、幻读。

评价: 性能最高,但安全性极差,生产环境基本禁用

2. 读提交(Read Committed, RC)

  • 特点: 一个事务只能读到其他事务已经提交的数据。

  • 现象: 解决了脏读,但存在不可重复读和幻读。

  • 评价: 许多主流数据库(如Oracle, SQL Server)的默认隔离级别。

3. 可重复读(Repeatable Read, RR)

  • 特点: 保证在同一个事务内,多次读取同一条记录的结果是一致的。

  • 现象: 解决了脏读、不可重复读、幻读。( 理论上RR仍存在幻读,但MySQL的InnoDB引擎通过Next-Key Lock(间隙锁)在很大程度上解决了幻读问题。)

  • 评价: MySQL的默认隔离级别,兼顾了性能与数据一致性。

防止不可重复读:

防止幻读:

4.串行化(Serializable)

  • 特点: 最高的隔离级别。所有事务按顺序排队执行。

  • 现象: 解决所有并发问题(脏读、不可重复读、幻读)。

  • 评价: 它会对读取的每一行数据都加锁,会导致大量的超时和锁竞争,性能极低,除非对数据一致性有极端严格的要求,否则不使用。

可以看到,阻塞的时候,mysql不会有输出,也不会让你执行下一步操作。

总结:

相关推荐
IMPYLH9 小时前
Linux 的 users 命令
linux·运维·服务器·前端·数据库·bash
Nontee9 小时前
三大范式是什么?
java·前端·数据库
天海华兮9 小时前
【优】B+树,Mysql优化 慢查询 执行计划 优化表结构 避免死锁 大量插入数据大数据后果
b树·mysql·死锁·慢查询·优化表结构·大量插入数据
步十人9 小时前
【MySQL】进阶01-存储引擎
数据库·mysql
六月雨滴9 小时前
归档日志备份
数据库·oracle·dba
白露与泡影10 小时前
自己用 ai 写了个链接 mysql 数据库的 mcp 工具
数据库·人工智能·mysql
我是一颗柠檬10 小时前
【MySQL全面教学】MySQL聚合函数与分组Day5(2026年)
数据库·后端·mysql·database
牛马鸡niumasi10 小时前
Mysql:事务管理(中)
数据库·mysql
字节高级特工10 小时前
Redis事务:简单但实用的打包执行
数据库·redis·后端·缓存