mysql中的事务控制:BEGIN、COMMIT与ROLLBACK

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

MySQL 中的

BEGIN
COMMIT
ROLLBACK
是手动控制事务的核心语句,但它们**不保证自动开启事务**——是否真正进入事务状态,取决于当前会话的
autocommit
设置。

autocommit 关闭才是事务生效的前提

MySQL 默认开启

autocommit=1
,此时每条 DML 语句(如
INSERT
UPDATE
)都会立即提交,
BEGIN
后执行的语句仍可能被自动提交,导致
ROLLBACK
失效。

必须先执行
SET autocommit = 0
,再用
BEGIN
(或
START TRANSACTION
)显式开启事务
BEGIN
本身不是 SQL 标准关键字,在 MySQL 中是
START TRANSACTION
的同义词,但不带任何隐式设置作用
某些客户端(如 phpMyAdmin、MySQL Workbench)可能默认关闭
autocommit
,但脚本或连接池中往往不会,不能依赖

COMMIT 和 ROLLBACK 的边界很明确

事务从

BEGIN
(或
START TRANSACTION
)开始,到
COMMIT
ROLLBACK
结束。之后的语句不属于该事务,也不会被回滚。

COMMIT
后,所有修改永久写入磁盘(受存储引擎和刷盘策略影响),无法撤销
ROLLBACK
仅能回滚当前未提交事务中的修改;如果中间执行过
COMMIT
,之前已提交的部分不可逆
执行
ROLLBACK
后,事务结束,后续语句需重新
BEGIN
才能再次开启事务

嵌套事务在 MySQL 中不存在

MySQL 不支持真正的嵌套事务。

BEGIN
后再写一个
BEGIN
,不会创建子事务,而是被忽略或报错(取决于版本和 SQL 模式)。

想实现“部分回滚”,只能靠
SAVEPOINT
:例如
SAVEPOINT sp1
ROLLBACK TO sp1
SAVEPOINT
不会结束事务,
ROLLBACK TO
后仍可继续
COMMIT
ROLLBACK
注意
SAVEPOINT
名称不能重复,否则后一次会覆盖前一次

常见误用场景与示例

下面这段代码在

autocommit=1
下运行,
ROLLBACK
实际无效:

SET autocommit = 1;
BEGIN;
INSERT INTO users(name) VALUES('Alice');
ROLLBACK;

正确写法应为:

SET autocommit = 0;
BEGIN;
INSERT INTO users(name) VALUES('Alice');
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;

或者更稳妥地,用标准语法并显式控制:

SET autocommit = 0;
START TRANSACTION;
INSERT INTO users(name) VALUES('Bob');
DELETE FROM logs WHERE created_at < NOW() - INTERVAL 7 DAY;
COMMIT;

最容易被忽略的是:应用层连接(如 Python 的

pymysql
、Java 的
Connection
)通常默认开启
autocommit
,且事务状态不跨请求保持——每次 HTTP 请求都得自己重置
autocommit
并管理
BEGIN/COMMIT/ROLLBACK

相关推荐