mysql执行SQL时事务是何时开启的_mysql事务执行顺序说明

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

MySQL 事务默认不是自动开启的,而是按需显式或隐式启动

MySQL 的

AUTOCOMMIT
默认为
1
(开启),这意味着每条单独的 DML 语句(如
INSERT
UPDATE
DELETE
)都会立即提交,不处于事务中。只有当你执行
BEGIN
START TRANSACTION
或设置
AUTOCOMMIT=0
后,后续语句才进入同一个事务上下文。

显式开启事务后,事务从第一条 DML 开始生效,而非从 BEGIN 开始计时

BEGIN
START TRANSACTION
本身不修改数据,只是标记事务边界起点;真正让事务“活起来”的是第一条可写操作。例如:

START TRANSACTION;
SELECT @x := 1;  -- 不影响事务状态(纯查询,无锁、不计入事务)
INSERT INTO t VALUES (1);  -- 此刻事务才真正持有行锁、写入 undo log
UPDATE t SET a=2 WHERE id=1;  -- 属于同一事务

注意:

SELECT
在默认隔离级别下是快照读,不触发事务锁,除非加
FOR UPDATE
LOCK IN SHARE MODE

隐式事务开启只对某些语句有效,且受存储引擎限制

以下语句在

AUTOCOMMIT=1
下会**自动开启并立即提交**一个隐式事务(仅限支持事务的引擎,如 InnoDB):

INSERT
UPDATE
DELETE
CREATE TABLE ... SELECT
DROP TABLE
ALTER TABLE
(部分操作)

但这些都不是“可回滚的多语句事务”——它们各自独立,无法用

ROLLBACK
撤销前面已执行的语句。比如:

INSERT INTO t VALUES (1);
UPDATE t SET a=2;  -- 即使没写 COMMIT,这两条也已各自提交

想跨语句回滚,必须先关

AUTOCOMMIT
或用
START TRANSACTION
包裹。

事务执行顺序严格遵循语句到达 server 的时间顺序,但可见性取决于隔离级别

事务内语句按客户端发送顺序执行,但其他事务能否看到中间结果,由隔离级别决定:

READ UNCOMMITTED
:其他事务能立刻看到未提交修改(脏读)
READ COMMITTED
:每次
SELECT
都读取最新已提交快照
REPEATABLE READ
(InnoDB 默认):事务第一次
SELECT
建立快照,后续读都复用
SERIALIZABLE
:所有
SELECT
隐式加锁,强制串行

关键点:事务顺序 ≠ 提交顺序。两个并发事务可能因锁等待、死锁检测等原因,实际提交顺序与执行顺序不一致。

最容易被忽略的是:DDL 语句(如

ALTER TABLE
)在 InnoDB 中会隐式提交当前事务,哪怕它出现在
START TRANSACTION
之后。这意味着你不能在事务中安全地混合 DDL 和 DML 并指望整体回滚。

相关推荐