我看到一些奇怪的行为,对于完全不相关的查询已多次发生。
Sql查询中的COMMIT TRANSACTION语句似乎被忽略了,尽管没有发生错误,但是在该进程被终止之前会对表进行锁定。
以下是一个例子:
BEGIN TRY
BEGIN TRANSACTION
UPDATE Elements.ProductDeparture
SET DurationDays = 5,
FinishDate = DATEADD(day, 4, DepartureDate)
WHERE DepartureCode LIKE 'PPAF%'
AND ProductID = 2359
COMMIT TRANSACTION
END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE()
ROLLBACK
END CATCH
查询没有出现错误(如果在没有事务的情况下运行它就可以完成)。该行为是可重现的(即每次运行上述查询时都会发生,而不是间歇性地发生)。
对于在事务中运行的完全不相关的查询,现在发生了两次。
这是奇怪的一点。我们在开发环境和测试环境中运行它,没有任何问题。在生产中运行它会导致进程无法完成,对表进行锁定,直到进程被终止。它们都是SQL Server 2005环境。
是否有任何SQL Server数据库设置可能导致这种奇怪的行为?到目前为止,大约有5位开发人员已经看过它,从未见过类似的东西。
答案 0 :(得分:3)
一些想法:
ROLLBACK
对它自己没有任何作用:您需要TRAN
或TRANSACTION
。 有关详细信息,请参阅:Nested stored procedures containing TRY CATCH ROLLBACK pattern?
所以,就像这样
SET XACT_ABORT, NOCOUNT ON
DECLARE @starttrancount int
BEGIN TRY
SET @starttrancount = @@TRANCOUNT
IF @starttrancount = 0
BEGIN TRANSACTION
UPDATE Elements.ProductDeparture
SET DurationDays = 5,
FinishDate = DATEADD(day, 4, DepartureDate)
WHERE DepartureCode LIKE 'PPAF%'
AND ProductID = 2359
IF @starttrancount = 0
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @starttrancount = 0
ROLLBACK TRANSACTION
PRINT 'Error: ' + ERROR_MESSAGE()
END CATCH
答案 1 :(得分:1)
测试@@ TRANCOUNT变量 - 在交易之前 - 如果它&gt; 0 - 然后正在进行外部事务。所以 - 在这种情况下,你的提交只会减少@@ TRANCOUNT的值,并且实际上不会提交更改
只有最外部的提交(将@@ trancount减少为0)才能修复更改