mysql中commit无效的最常见原因是未真正开启事务:默认autocommit=1时,每条dml语句自动提交,commit无事可做;须用start transaction显式开启事务,再执行dml,最后commit。

必须显式执行 COMMIT,且前提是事务已真正开启——默认 autocommit=1 时,INSERT 语句一执行就落地,COMMIT 无效。
MySQL 中 COMMIT 为什么没效果?
最常见原因是:你没真正进入事务上下文。MySQL 默认开启自动提交(@@autocommit = 1),此时每条 INSERT、UPDATE 或 DELETE 都是独立事务,立即写盘。哪怕你写了 COMMIT,它也无事可做。
- 用
SELECT @@autocommit;确认当前状态;返回1就说明自动提交开着 - 别依赖
SET autocommit = 0来“启动事务”,这只是关闭自动提交,后续所有 DML 都挂起,但没事务名、没嵌套控制,容易漏COMMIT导致锁表 - 正确做法是统一用
START TRANSACTION;(或BEGIN;)显式开启,再执行 DML,最后COMMIT;
SQL Server 提交失败的典型表现
COMMIT TRAN 本身极少报错,但常出现“看似提交成功,实际只部分生效”的假象。根本原因不是提交失败,而是前置语句已出错却未中断流程。
- 比如主键重复或外键约束失败,SQL Server 默认只回滚出错那一条语句,其余仍留在事务中——除非你启用了
SET XACT_ABORT ON - 不配
TRY...CATCH块的话,COMMIT TRAN会照常执行,把前面成功的操作永久保存,破坏原子性 - 务必在
BEGIN TRY内执行 DML,在BEGIN CATCH中调用ROLLBACK TRAN,否则COMMIT就是危险操作
INSERT 多行时事务边界怎么划?
批量 INSERT 是单条语句,不是多条语句的简写——它要么全成功,要么全失败,天然具备原子性。但是否纳入事务,取决于你是否把它放在 START TRANSACTION 和 COMMIT 之间。
- 例如:
INSERT INTO t(a,b) VALUES (1,'x'),(2,'y'),(3,'z');这是一条语句,执行失败则整条回滚(即使引擎支持部分插入,InnoDB 也不允许) - 但如果你分三次执行
INSERT,又没包在事务里,那就三段独立操作,彼此无关联 - 想保证“这三行一起成功或一起失败”,就必须用
START TRANSACTION包裹全部三条(或一条批量 INSERT)
事务不是靠 COMMIT 启动的,而是靠 START TRANSACTION 或等效命令定义边界;COMMIT 只是终点标记。最容易被忽略的是错误处理缺失——没有捕获异常就盲目 COMMIT,等于把半截数据钉死在库中。











