经过两天的批量测试,回滚并尝试..catch,我的思绪仍然模糊不清。为了澄清我的问题,我将我正在做的事分成两步。
1。回滚批次 正如在线书籍所解释的那样,在批处理中,只有批处理在事务中并且批处理中的错误导致事务回滚,否则执行的语句不能回滚。
所以我把批处理放到像
这样的交易中begin transaction
create table A ...
insert into A values...
insert into A values... (error here!)
insert into A values...
GO
rollback
这适用于错误输出,并且没有创建表
(1 row(s) affected)
Msg 213, Level 16, State 1, Line 5
Column name or number of supplied values does not match table definition.
Msg 208, Level 16, State 1, Line 1
Invalid object name 'A'.
但是,即使在事务中没有错误,也会执行回滚。为了处理这种情况,我使用TRY ... CATCH,如2。
2。使用TRY ... CATCH
BEGIN TRY
begin transaction
create table A ...
insert into A values...
insert into A values... (error here!)
insert into A values...
--GO
END TRY
BEGIN CATCH
ROLLBACK
END CATCH
这次不再允许声明GO了。 S * o在这种情况下,批处理是BEGIN TRY
和END TRY
之间的整个块? *
另外,结果并不像我预期的那样。 CREATE TABLE
和第一个插入仍然执行但没有回滚。
我再次搜查。 似乎我需要SET XACT_ABORT ON
才能在触摸提交之前将这些执行的语句记录为未提交。我在这里理解的是对的吗?如果是这样,我在这种情况下没有添加任何提交语句。
顺便说一句,测试是在SQL SERVER 2012上完成的。感谢您的任何澄清!
答案 0 :(得分:1)
它不允许GO语句的原因是try和catch必须是此MSDN article中提到的同一批次的一部分。它说明了;
“每个TRY ... CATCH构造必须在一个批次内,存储 程序或触发器。例如,您不能放置TRY块 一个批次和另一个批次中的关联CATCH块。该 以下脚本会生成错误:“
BEGIN TRY SELECT * FROM sys.messages WHERE message_id = 21; END TRY GO -- The previous GO breaks the script into two batches, -- generating syntax errors. The script runs if this GO -- is removed. BEGIN CATCH SELECT ERROR_NUMBER() AS ErrorNumber; END CATCH; GO
关于如何处理这个问题的另一个想法,看看问题Nested stored procedures containing TRY CATCH ROLLBACK pattern?上的gbns答案,因为他讨论了他处理交易的模式/模板,包括使用(和原因)XACT_ABORT和其他漂亮的特征。我还建议阅读gbns回答中的相关链接
Aaron Betrand对同一问题的回答是指Erland Somarsskog的article on error handling与gbn的回答非常相似。
即使原始问题的标题与嵌套交易有关,但它仍然适用于我认为的情况。
答案 1 :(得分:0)
尝试在脚本开头使用SET XACT_ABORT ON
。查看XACT_ABORT
MSDN参考页here