我们在这里遇到了一个问题,我无法弄清楚它为什么会表现得如此。
给定 TSQL (SQL Server 2008R2) 中的以下两个(简化)存储过程
create procedure [datetransaction1]
as
begin
begin try
begin transaction
declare @a datetime
exec datetransaction2 '2013-02-02 22:21', @a output
select @a
exec datetransaction2 '2013-020222:22', @a output
select @a
exec datetransaction2 '2013-02-02 22:23', @a output
select @a
commit transaction
end try
begin catch
print 'Catch'
end catch
end
和
create procedure [dbo].[datetransaction2] @text nvarchar(100), @res datetime OUTPUT
AS
BEGIN
BEGIN TRY
if (LEN(@text) = 16) SET @text = replace(@text, ' ', 'T') + ':00.000'
else if (LEN(@text) = 19) SET @text = replace(@text, ' ', 'T') + '.000'
else SET @text = replace(@text, ' ', 'T')
PRINT 'trydate:' + @text
SELECT @res =convert(datetime, @text, 126)
END TRY
BEGIN CATCH
PRINT ERROR_SEVERITY()
PRINT 'errordate:' + @text
END CATCH
END
如果然后执行exec datetransaction1
,我们会看到所有 3 个调用datetransaction2
都已执行,第一个和最后一个(如预期的那样)正确运行,第二个CATCH
进入datetransaction2
.
到现在为止还挺好。
但随后我们进入 catch 块,datetransaction1
并显示事务不可提交的消息:
Msg 266, Level 16, State 2, Procedure datetransaction1, Line 0
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
Msg 3998, Level 16, State 1, Line 1
Uncommittable transaction is detected at the end of the batch. The transaction is rolled back.
这不应该发生(我认为)。我们在子过程中发现了错误,为什么事务会突然变得不可提交?
有人可以向我解释吗?
请注意,我们可能会找到解决此问题的方法,但我对它背后的想法更感兴趣。为什么这个交易在这里突然变得不可提交?