rollback仅对未提交的delete有效,须满足三条件:显式事务内、未commit、同一会话;sql server默认自动提交,未begin transaction则删除即生效;已提交者需依赖full恢复模式及日志备份恢复。

ROLLBACK 能立刻回退,但前提是事务没提交
未提交的 DELETE 只能靠 ROLLBACK 撤销,而且必须满足三个条件:语句在显式事务内、事务尚未 COMMIT、你还在同一个数据库会话中。
SQL Server 默认每个语句是自动提交的,所以如果没写 BEGIN TRANSACTION,DELETE 执行完就落地了,ROLLBACK 无效。
- 正确姿势:
BEGIN TRANSACTION; DELETE FROM users WHERE id = 100; ROLLBACK; - 常见误判:用 SSMS 执行完
DELETE后关掉查询窗口,再开新窗口执行ROLLBACK—— 不行,会报错The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION - 检查当前会话是否在事务中:
SELECT @@TRANCOUNT;返回 0 表示没事务,返回 1 或更大值才可安全ROLLBACK
SSMS 默认 autocommit=ON 是最大陷阱
SQL Server Management Studio(SSMS)默认开启自动提交,意味着每条 DELETE 都是独立事务,执行即生效。这不是 bug,是设计行为,但极易让人误以为“还能撤”。
- 验证方式:
SELECT DATABASEPROPERTYEX(DB_NAME(), 'IsAutoCommit') —— 返回 1 即开启 - 临时关闭(仅当前会话):
SET IMPLICIT_TRANSACTIONS ON;,之后每条 DML 都需显式COMMIT或ROLLBACK - 不建议全局改:SQL Server 没有类似 MySQL 的
autocommit=OFF全局配置项;SSMS 里也无界面开关,只能靠习惯或脚本前置
已执行 COMMIT 的 DELETE 怎么办?看恢复模式和日志备份
一旦 COMMIT 成功,ROLLBACK 就彻底失效。此时能否恢复,只取决于两件事:recovery_model_desc = 'FULL' 和有没有未截断的事务日志备份。
- 查恢复模式:
SELECT recovery_model_desc FROM sys.databases WHERE name = 'your_db';,结果不是FULL就基本没戏 - 查最近一次日志备份时间:
SELECT TOP 1 backup_finish_date FROM msdb.dbo.backupset WHERE database_name = 'your_db' AND type = 'L' ORDER BY backup_finish_date DESC; - 如果日志备份存在且覆盖误删前的时间点,可用
RESTORE LOG ... WITH STOPAT恢复到误删前一秒;否则只能依赖第三方工具(如ApexSQL Log)解析 LDF 文件——但这要求 LDF 没被收缩或覆盖
别等出事才想起检查 recovery model
很多 DBA 第一次遇到误删时才去查 recovery_model_desc,发现是 SIMPLE,当场沉默。这个值不是“出了问题再改就有用”的,它影响的是日志是否被定期截断。改回 FULL 后必须立刻做一次完整备份,否则后续日志仍无法用于时间点恢复。
真正关键的操作,是在数据库创建后、上线前,就跑一遍:ALTER DATABASE [your_db] SET RECOVERY FULL;,再立即执行一次 BACKUP DATABASE。漏掉这一步,等于没装刹车片。










