mysql事务是什么_mysql事务核心概念讲解

来源:这里教程网 时间:2026-02-28 20:52:15 作者:

MySQL 事务不是“功能开关”,而是一套**以

START TRANSACTION
为起点、以
COMMIT
ROLLBACK
为终点的执行契约**——它只对支持事务的存储引擎(如
InnoDB
)生效,
MyISAM
等引擎完全无视事务语句。

事务本质:为什么不能靠“写两条 UPDATE 就完事”?

转账场景最典型:A 减 100、B 加 100。如果中间断电或程序崩溃,只执行了第一条,数据库就永远不一致了。事务解决的不是“语法问题”,而是“状态可靠性问题”——它让 MySQL 能在出错时倒带回原始状态。

autocommit=1
(默认)下,每条 SQL 都是独立事务,
START TRANSACTION
才真正开启多语句协同控制
事务不是锁表工具,但会隐式加行级锁(
InnoDB
),并发高时可能引发
Lock wait timeout exceeded
DDL 语句(如
ALTER TABLE
)会自动触发隐式提交,导致当前事务提前结束

ACID 四特性里,最容易被误解的是“一致性”

很多人以为“一致性”等于“数据正确”,其实它更接近“约束守门员”:只要违反了主键、外键、

CHECK
、非空等约束,事务就会被强制回滚——哪怕你没写
ROLLBACK

原子性靠
undo log
实现:记录反向操作(比如减 100 的 undo 是“加 100”)
持久性靠
redo log
保证:即使断电,已
COMMIT
的修改也能从日志恢复
隔离性不是“绝对隔离”,而是通过
MVCC + 锁
实现读写不互斥,但不同隔离级别表现差异极大

四个隔离级别怎么选?看业务容忍度,别盲目调高

REPEATABLE READ
(InnoDB 默认)不是银弹。它能防不可重复读,但幻读仍存在(比如
SELECT ... FOR UPDATE
后插入新行)。真要杜绝幻读,得用
SERIALIZABLE
,但代价是所有写操作串行化,QPS 断崖下跌。

READ COMMITTED
:适合高并发读多写少场景(如订单查询),每次
SELECT
都读最新已提交版本
REPEATABLE READ
:适合需要多次读取同一快照的场景(如报表生成),但需配合
SELECT ... FOR UPDATE
或间隙锁防幻读
临时改级别用
SET TRANSACTION ISOLATION LEVEL xxx
,仅对当前会话生效

显式事务的坑:SAVEPOINT 不是万能回滚点

SAVEPOINT
只能回滚到该点之后的操作,且不能跨事务生命周期。更关键的是:它不释放锁——如果在保存点前已锁住某行,回滚到该点后,那行依然被锁着,其他事务照样阻塞。

正确用法:
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
SAVEPOINT sp1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- 若第二步失败,可回滚到 sp1,保留第一步结果
ROLLBACK TO sp1;
常见误用:在循环中反复
SAVEPOINT
却不
RELEASE SAVEPOINT
,导致内存泄漏(尤其长事务)
ROLLBACK
会清除所有保存点;
COMMIT
也会自动清空

事务不是越长越好,也不是越多越好。一个事务里混进慢查询、大范围扫描或外部 API 调用,轻则锁表,重则拖垮整个库。真实系统里,90% 的事务应该控制在 100ms 内完成,且只包裹真正需要原子性的那几条语句。

相关推荐