/*开始事务*/ BEGIN TRAN Update_data with mark UPDATE bookpub SET 书名='C#技术方案宝典'--修改操作 WHERE 书号='5'; SELECT 书号,书名,作者 FROM bookpub; /*回滚事务*/ ROLLBACK TRAN Update_data SELECT 书号,书名,作者 FROM bookpub;
讲讲这段回滚事务,with mark是干啥的?
WITH MARK 在事务回滚中的作用详解
你问的 WITH MARK 是一个非常专业且不常见的高级功能。它不是用来控制回滚本身的,而是用来在日志中做一个“大记号”,用于后续的定点恢复。
我先把结论给你,再逐行拆解。
一、一句话解释 WITH MARK
WITH MARK不是在回滚时用的,而是在BEGIN TRAN时打一个“书签”,以后可以从这个书签点恢复整个数据库。
你这段代码虽然写了 ROLLBACK,但 WITH MARK 在这次回滚中没有任何作用。
二、这段代码逐行分析
第 1–2 行
sql
BEGIN TRAN Update_data with mark
开启一个名为
Update_data的事务同时在事务日志中打一个命名标记点
第 3–5 行
sql
UPDATE bookpub SET 书名='C#技术方案宝典'WHERE 书号='5';SELECT 书号,书名,作者 FROM bookpub;
修改数据
查询验证(此时数据已改,但未真正落盘)
第 6–8 行
sql
ROLLBACK TRAN Update_dataSELECT 书号,书名,作者 FROM bookpub;
回滚整个事务
再次查询时,数据恢复原样
三、WITH MARK 的真正用途(非常重要)
WITH MARK 与 ROLLBACK 无关。它用于以下场景:
典型用途:数据库恢复到某个“业务标记点”
sql
-- 1. 开始一个带标记的事务BEGIN TRAN point1 WITH MARK '软件发布前'-- 2. 执行一系列重要更新UPDATE ...-- 3. 提交COMMIT TRAN point1
以后你可以这样恢复:
sql
RESTORE DATABASE MyDB FROM DISK = 'backup.bak'WITH STOPATMARK = '软件发布前'
👉 这样数据库会精确恢复到 point1 事务提交的那一刻。
四、为什么在你的例子里 WITH MARK 没起作用?
因为你是 ROLLBACK,不是 COMMIT:
| 情况 | WITH MARK 是否生效 |
|---|---|
COMMIT 提交 | ✅ 标记会留在日志中 |
ROLLBACK 回滚 | ❌ 标记被一起回滚,不会保留 |
在你这段代码中,WITH MARK 写了等于没写。
五、WITH MARK 的词源与理解
| 单词 | 含义 |
|---|---|
MARK | 标记、记号、书签 |
就像在一本书的某一页夹一个书签,以后可以直接翻到这一页。
六、总结你的例子真正在做什么
| 步骤 | 作用 |
|---|---|
BEGIN TRAN with mark | 开启事务 + 打算做标记 |
UPDATE + SELECT | 修改并查看 |
ROLLBACK | 撤销所有修改 |
WITH MARK | 被浪费了(因为没提交) |
👉 如果你想看 WITH MARK 的真实效果,需要把 ROLLBACK 换成 COMMIT。
七、一句话结论
WITH MARK不是回滚命令,而是给事务“起一个可恢复的名字”,用于未来的数据库级别恢复。
在你这段回滚代码中,它没有任何实际作用。