SQL Server 2005事务提交被忽略

时间:2011-12-20 06:35:31

标签: sql-server sql-server-2005

我看到一些奇怪的行为,对于完全不相关的查询已多次发生。

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位开发人员已经看过它,从未见过类似的东西。

2 个答案:

答案 0 :(得分:3)

一些想法:

  • 如果出现任何错误,请使用SET XACT_ABORT ON强制回滚和锁定释放。这也会抑制错误266
  • 首先测试现有交易,我怀疑这是您的问题
  • 在回滚前测试事务状态
  • ROLLBACK对它自己没有任何作用:您需要TRANTRANSACTION

有关详细信息,请参阅: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)才能修复更改