mysql如何使用事务_mysql事务控制语法解析

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

事务必须显式开启,
BEGIN
START TRANSACTION
缺一不可

MySQL 默认是自动提交模式(

autocommit=1
),每条 DML 语句单独成事务,执行完立刻生效。想把多条语句打包进一个事务,必须先显式开启——只写
COMMIT
ROLLBACK
没用,它们不会触发隐式开始。

常见错误:直接写

UPDATE t1 SET x=1; UPDATE t2 SET y=2; COMMIT;
,结果两条更新各自提交,无法回滚。

BEGIN
START TRANSACTION
完全等价,任选其一即可
不推荐用
BEGIN WORK
,虽兼容但冗余
开启后,后续所有 DML(
INSERT
/
UPDATE
/
DELETE
)都暂存在当前事务中,直到
COMMIT
ROLLBACK

SAVEPOINT
不是必需的,但能解决部分回滚需求

标准事务只有全提交或全回滚两种结局。如果中间某步出错,又不想放弃前面已成功的操作,就得靠

SAVEPOINT
设立标记点。

例如:插入主表、插入从表、更新统计表 —— 若第三步失败,只回滚到第二步之后的状态,保留前两步。

定义:
SAVEPOINT sp1;
,名字可自定义,同一事务内可设多个
回滚到某点:
ROLLBACK TO SAVEPOINT sp1;
(注意不是
ROLLBACK TO sp1
释放某个保存点:
RELEASE SAVEPOINT sp1;
,不影响事务本身
事务结束(
COMMIT
ROLLBACK
)会自动清除所有保存点

隐式提交语句会让事务意外终止

有些 SQL 语句执行时会强制提交当前事务,哪怕你没写

COMMIT
,事务也立刻结束。这是最容易踩坑的地方,尤其在存储过程或混合 DDL/DML 场景中。

典型触发隐式提交的语句包括:

CREATE TABLE
DROP TABLE
ALTER TABLE
TRUNCATE TABLE
LOCK TABLES
FLUSH LOGS
等。

示例:
BEGIN; INSERT INTO t VALUES(1); CREATE TABLE tmp(id INT); INSERT INTO t VALUES(2); COMMIT;
→ 实际只有最后一条
INSERT
受事务保护
SELECT
不会隐式提交,但
SELECT ... FOR UPDATE
SELECT ... LOCK IN SHARE MODE
属于事务内加锁操作,仍需在事务中使用
DDL 类操作尽量放在事务外,或确认是否真需要与 DML 绑定

事务隔离级别影响可见性,
SET TRANSACTION ISOLATION LEVEL
必须在
BEGIN
前设置

MySQL 的默认隔离级别是

REPEATABLE READ
,但如果你需要读已提交(
READ COMMITTED
)来避免间隙锁或适配其他数据库行为,得手动改——而且时机很关键。

错误写法:

BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
→ 此时事务已开启,该语句无效,级别仍是启动时的默认值。

正确方式:在
BEGIN
前执行,如
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; BEGIN;
也可用会话级设置:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
,之后所有新事务都生效
READ UNCOMMITTED
SERIALIZABLE
同理,不能在事务中动态切换
事务的边界比看起来更“脆”:一条 DDL、一个连接中断、甚至某些客户端自动重连行为,都可能让
BEGIN
形同虚设。实际写业务逻辑时,别只盯着
COMMIT
写在哪,先确认事务是不是真的从你想的位置开始了。

相关推荐