MySQL事务(一)

我们之前学完了MySQL的索引,今天我们要翻过第二个大难关 --- MySQL的事务

一、为什么需要事务

在日常开发中,我们对数据库的操作本质就是 CRUD(增删改查)。如果这些操作不加任何控制,会带来很多问题,比如:

  • 数据更新了一半程序崩溃
  • 多个用户同时修改同一条数据导致混乱
  • 数据写入后丢失(比如服务器宕机)
  • 数据前后状态不一致

举个经典例子:买票系统的流程

  1. 扣库存
  2. 生成订单
  3. 支付

如果执行到一半失败,比如库存扣了但订单没生成,就会造成严重问题

因此,我们需要一种机制,让一组操作要么全部成功,要么全部失败

这就是 事务(Transaction) 的意义


二、什么是事务?

事务本质上是一组 SQL 语句的集合,这些语句:

  • 在逻辑上是相关的
  • 要么全部执行成功
  • 要么全部失败回滚

简单理解:

事务 = 一组"绑定在一起"的 SQL 操作

例如:

如果中间任何一步失败,就可以:

复制代码
ROLLBACK;
也可以savepoint [回滚点],之后rollback to [回滚点]即可回滚到该位置
操作 是否结束事务 是否需要commit

|-------------|---|-----|
| ROLLBACK | 是 | 不需要 |

|-------------------------|---|--------|
| ROLLBACK TO savepoint | 否 | 需要(通常) |


三、事务的四大特性(ACID)

事务之所以可靠,是因为它满足四个核心特性:

1. 原子性(Atomicity)

事务是不可分割的整体:

  • 要么全部成功
  • 要么全部失败

如果执行过程中出错,会自动回滚到最初状态。


2. 一致性(Consistency)

事务执行前后,数据库必须保持一致状态。

例如:

  • 转账前总金额 = 转账后总金额
  • 数据必须符合约束(主键、外键等)

3. 隔离性(Isolation)

多个事务可以同时执行,但互不干扰。

否则会出现:

  • 读到别人未提交的数据
  • 数据被反复修改导致不一致

4. 持久性(Durability)

事务一旦提交:

  • 数据会永久保存
  • 即使数据库宕机也不会丢失

四、事务是如何实现的?

事务并不是数据库"天生就有"的,而是为了简化应用开发而设计的机制。

它帮我们解决:

  • 并发问题
  • 异常回滚
  • 数据一致性

开发者只需要:

复制代码
BEGIN(这里也可以使用start transaction);
...
COMMIT;

就可以编写事务


五、MySQL中事务的支持

注意:不是所有存储引擎都支持事务

引擎 是否支持事务
InnoDB ✅ 支持
MyISAM ❌ 不支持
MEMORY ❌ 不支持

查看方式:

复制代码
SHOW ENGINES;

实际开发中必须使用 InnoDB,因为只有该引擎支持事务,而事务在实际开发中十分重要


六、事务的提交方式

MySQL事务有两种提交方式:

1. 自动提交(默认)

复制代码
SHOW VARIABLES LIKE 'autocommit';

默认:

复制代码
autocommit = ON

意味着:

每一条 SQL 都是一个独立事务,并自动提交


2. 手动提交

关闭自动提交:

复制代码
SET AUTOCOMMIT = 0;

意味着:

autocommit=0 的情况下,多个 SQL 会自动归属于同一个事务,必须显式执行 COMMIT 才会提交


七、事务的基本操作

1. 开启事务

复制代码
BEGIN;
-- 或
START TRANSACTION;

2. 提交事务

复制代码
COMMIT;

只要commit之后数据永久生效


3. 回滚事务

复制代码
ROLLBACK;

回到事务开始前


4. 保存点(Savepoint)

可以实现"局部回滚"

复制代码
SAVEPOINT s1;

-- 执行操作

ROLLBACK TO s1;

八、事务的重要结论(非常关键)

通过实验可以得到几个重要结论:

1. 事务必须提交才会生效

复制代码
BEGIN;
INSERT ...
-- 没有 COMMIT

其他会话看不到数据(前提是隔离等级不是读未提交,在该隔离登记下就算不commit其他会话也可以看到)


2. 客户端异常退出会自动回滚

如果事务未提交:

MySQL 会自动回滚


3. COMMIT 后数据永久生效

即使:

  • 程序崩溃
  • 客户端断开

数据依然存在


4. BEGIN 会打破自动提交

即使:

复制代码
autocommit = ON

只要执行:

复制代码
BEGIN;

就进入手动事务模式

这就说明autocommit 只影响隐式事务(未显式使用 BEGIN)的提交行为;
一旦使用 BEGIN / START TRANSACTION 显式开启事务,就
完全不受 autocommit 影响


5. 单条 SQL 也是事务

在自动提交模式下:

复制代码
INSERT INTO table VALUES (...);

本质上等价于:

复制代码
BEGIN;
INSERT ...
COMMIT;

为什么平时我们感到这样呢,因为系统默认是autocommit=no的~~


九、为什么需要隔离性?

数据库通常是多用户并发访问的:

  • 多个事务同时执行
  • 操作同一张表甚至同一行数据

如果没有隔离:

数据会混乱

例如:

  • A 修改数据
  • B 同时读取

问题来了:

B 是否应该看到 A 未提交的数据?

这就是 隔离性要解决的问题


十、事务隔离级别与更改

MySQL 提供了四种隔离级别:

隔离级别 特点
Read Uncommitted 可以读未提交数据
Read Committed 只能读已提交数据
Repeatable Read 可重复读(MySQL默认)
Serializable 串行执行

如何查看当前是什么隔离级别呢:

写法 含义

|----------------------------------|------|
| @@global.transaction_isolation | 全局默认 |

|-----------------------------------|------|
| @@session.transaction_isolation | 当前连接 |

|---------------------------|----------|
| @@transaction_isolation | 当前连接(简写) |

如何更改呢:

下次进入MySQL就会默认成为global.transaction_isolation设置的状态


十一、Read Uncommitted(读未提交)

特点:

可以读取其他事务未提交的数据

这会导致:

脏读(Dirty Read)

示例:

B(右边) 读到了 A(左边) 未提交的数据

如果 A 回滚:

B 读到的是"错误数据"


总结

  • 几乎没有隔离
  • 性能高
  • 风险极大
  • 实际生产基本不用

十二、Read Committed(读已提交)

特点:

只能读取 已经提交的数据


解决的问题

✔ 避免脏读


仍然存在的问题

不可重复读(Non-repeatable Read)

示例:

同一个事务中,两次读取结果不同


原因

因为:

每次 SELECT 都读取"最新已提交数据"


总结

特性 是否支持
脏读 ❌ 不会发生
不可重复读 ✅ 会发生
幻读 ✅ 可能发生

十二、小结

到目前为止,我们已经掌握:

事务基础

  • 什么是事务
  • ACID特性
  • 事务操作(BEGIN / COMMIT / ROLLBACK)

事务行为

  • 自动提交 vs 手动提交
  • 崩溃回滚机制
  • 单条SQL本质也是事务

隔离性核心问题

  • 并发访问带来的数据问题

两种隔离级别

  • Read Uncommitted(脏读)
  • Read Committed(解决脏读,但有不可重复读)

下一部分,我们将进入:

Repeatable Read(可重复读)与MVCC机制

这是 MySQL 中的核心内容,我们下一篇博客不见不散啦~~

相关推荐
%KT%1 小时前
Agent开发:自动查天气+景区推荐
linux·数据库·php
Yupureki1 小时前
《Linux网络编程》9.数据链路层原理
linux·运维·服务器·网络
顶点多余1 小时前
Socket编程实现UDP通信
linux·网络协议·udp
van久1 小时前
Day22:JWT 完整学习笔记 + 原理 + 面试题 + 帮助类封装
笔记·学习
切糕师学AI1 小时前
Remmina:Linux 平台的全能远程桌面客户端详解
linux·运维·远程控制·远程桌面·remmina
会编程的土豆1 小时前
MySQL 多表查询
开发语言·数据库·python·mysql
2403_883261091 小时前
PHP调用Codex处理PHP特定语法【操作】
jvm·数据库·python
dualven_in_csdn2 小时前
【assist】 需要用到的方法
linux·运维·服务器
minji...2 小时前
Linux 网络基础(二)HTTP协议,域名,URL,URI,认识HTTP的请求和响应
linux·服务器·网络·网络协议·http·tcp