Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 死锁与日志记录_Sql_Sql Server 2008_Logging_Deadlock - Fatal编程技术网

Sql 死锁与日志记录

Sql 死锁与日志记录,sql,sql-server-2008,logging,deadlock,Sql,Sql Server 2008,Logging,Deadlock,Web应用程序。 C#,SQL 2k8 在一个列表中,在执行实际的动态SQL并返回所需的记录之前,会发生很多事情 最近,我们为整个应用程序添加了一些代码(死锁问题),包括事务提交、回滚和重试X次,总共9码 这是一个很大的优点,我们真的需要它 但是 为了调试列表中可能出现的任何问题,我将动态SQL字符串保存在一个日志表中(它不存储过去几周的旧记录) 问题是:如果列表崩溃,现在就没有日志。因为回滚的东西 到目前为止,我最好的办法是给名单打两次电话: “检查”-模式,将创建动态SQL,将其保存在日志t

Web应用程序。 C#,SQL 2k8

在一个列表中,在执行实际的动态SQL并返回所需的记录之前,会发生很多事情

最近,我们为整个应用程序添加了一些代码(死锁问题),包括事务提交、回滚和重试X次,总共9码

这是一个很大的优点,我们真的需要它

但是

为了调试列表中可能出现的任何问题,我将动态SQL字符串保存在一个日志表中(它不存储过去几周的旧记录)

问题是:如果列表崩溃,现在就没有日志。因为回滚的东西

到目前为止,我最好的办法是给名单打两次电话:

  • “检查”-模式,将创建动态SQL,将其保存在日志tbl中,但不会执行

  • “列表”-模式将:

  • 2a。重新计算动态SQL

    2b。重用“检查模式”创建的动态SQL

    2a或2b都不会有太大的性能问题,因为列表存储过程中最昂贵的部分是动态sql的实际执行

    死锁重试部分只执行第二次db调用,这也很好

    还是。 我不是这个想法最快乐的人。 我想知道是否有更好的方法来实现这一点。

    您可以在事务期间使用(表)变量和TRY-CATCH块来保存数据。回滚后会保留变量

    如果您的翻译在存储过程中,则可以如下所示:

    BEGIN TRY
        BEGIN TRAN
    
        DECLARE @SQL NVARCHAR(MAX)
        SET @SQL = 'SELECT 1'
    
        RAISERROR('A',16,1)
    
        EXEC (@SQL)
    
        COMMIT
    
    END TRY
    BEGIN CATCH
        ROLLBACK
        SELECT @SQL --WRITE TO LOG TABLE
    
    END CATCH
    
    BEGIN TRY
    
        DECLARE @SQL NVARCHAR(MAX)
        SET @SQL = 'SELECT 1'
    
        RAISERROR('A',16,1)
    
        EXEC (@SQL)
    
    END TRY
    BEGIN CATCH
    
        DECLARE @ErrorMessage NVARCHAR(4000)
        DECLARE @ErrorSeverity INT
        DECLARE @ErrorState INT
    
        SELECT 
            @ErrorMessage = 'Error: ' + ERROR_MESSAGE() + '; SQL: ' + @SQL,
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE()
    
        RAISERROR (@ErrorMessage,@ErrorSeverity,@ErrorState)
    
    END CATCH
    
    如果您的事务在SP-in C#代码之外(通常这是一个更好的主意),您可以将变量连同发生的实际错误一起发送回应用程序。如下所示:

    BEGIN TRY
        BEGIN TRAN
    
        DECLARE @SQL NVARCHAR(MAX)
        SET @SQL = 'SELECT 1'
    
        RAISERROR('A',16,1)
    
        EXEC (@SQL)
    
        COMMIT
    
    END TRY
    BEGIN CATCH
        ROLLBACK
        SELECT @SQL --WRITE TO LOG TABLE
    
    END CATCH
    
    BEGIN TRY
    
        DECLARE @SQL NVARCHAR(MAX)
        SET @SQL = 'SELECT 1'
    
        RAISERROR('A',16,1)
    
        EXEC (@SQL)
    
    END TRY
    BEGIN CATCH
    
        DECLARE @ErrorMessage NVARCHAR(4000)
        DECLARE @ErrorSeverity INT
        DECLARE @ErrorState INT
    
        SELECT 
            @ErrorMessage = 'Error: ' + ERROR_MESSAGE() + '; SQL: ' + @SQL,
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE()
    
        RAISERROR (@ErrorMessage,@ErrorSeverity,@ErrorState)
    
    END CATCH
    
    您可以在事务期间使用(表)变量和TRY-CATCH块来保存数据。回滚后保留变量

    如果您的翻译在存储过程中,则可以如下所示:

    BEGIN TRY
        BEGIN TRAN
    
        DECLARE @SQL NVARCHAR(MAX)
        SET @SQL = 'SELECT 1'
    
        RAISERROR('A',16,1)
    
        EXEC (@SQL)
    
        COMMIT
    
    END TRY
    BEGIN CATCH
        ROLLBACK
        SELECT @SQL --WRITE TO LOG TABLE
    
    END CATCH
    
    BEGIN TRY
    
        DECLARE @SQL NVARCHAR(MAX)
        SET @SQL = 'SELECT 1'
    
        RAISERROR('A',16,1)
    
        EXEC (@SQL)
    
    END TRY
    BEGIN CATCH
    
        DECLARE @ErrorMessage NVARCHAR(4000)
        DECLARE @ErrorSeverity INT
        DECLARE @ErrorState INT
    
        SELECT 
            @ErrorMessage = 'Error: ' + ERROR_MESSAGE() + '; SQL: ' + @SQL,
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE()
    
        RAISERROR (@ErrorMessage,@ErrorSeverity,@ErrorState)
    
    END CATCH
    
    如果您的事务在SP-in C#代码之外(通常这是一个更好的主意),您可以将变量连同发生的实际错误一起发送回应用程序。如下所示:

    BEGIN TRY
        BEGIN TRAN
    
        DECLARE @SQL NVARCHAR(MAX)
        SET @SQL = 'SELECT 1'
    
        RAISERROR('A',16,1)
    
        EXEC (@SQL)
    
        COMMIT
    
    END TRY
    BEGIN CATCH
        ROLLBACK
        SELECT @SQL --WRITE TO LOG TABLE
    
    END CATCH
    
    BEGIN TRY
    
        DECLARE @SQL NVARCHAR(MAX)
        SET @SQL = 'SELECT 1'
    
        RAISERROR('A',16,1)
    
        EXEC (@SQL)
    
    END TRY
    BEGIN CATCH
    
        DECLARE @ErrorMessage NVARCHAR(4000)
        DECLARE @ErrorSeverity INT
        DECLARE @ErrorState INT
    
        SELECT 
            @ErrorMessage = 'Error: ' + ERROR_MESSAGE() + '; SQL: ' + @SQL,
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE()
    
        RAISERROR (@ErrorMessage,@ErrorSeverity,@ErrorState)
    
    END CATCH
    

    整个重试逻辑是在一个大型事务中,还是每次重试都会启动一个新事务?每次重试都是一个新事务?是一个大型事务中的整个重试逻辑,还是每次重试都会启动一个新事务?每次重试都是一个新事务我们不从SQL生成事务,因为事实上SQL可能是(某种程度上)死。事务和重试部分都是C#,我们在存储中执行所有操作procedures@Swoosh好的,正如我所说的,这是一个更好的主意。您仍然可以在SP中使用TRY/CATCH块来处理错误,并将它们与生成的动态sql一起发送回C(并从C做日志记录)此外,我认为您的两个SP的想法没有任何错误-确切地说是2b想法-一个SP准备并记录动态sql,另一个执行它。我们不从sql进行事务处理,因为事实上sql可能(有些)死。事务和重试部分都是C#,我们在存储中执行所有操作procedures@Swoosh好的,正如我所说的,这是一个更好的主意。您仍然可以在SP中使用TRY/CATCH块来处理错误,并将它们与生成的动态sql一起发送回C(并从C做日志记录)此外,我认为您的两个SP的想法没有什么错-确切地说,是两个SP-一个SP准备并记录动态sql,另一个SP执行动态sql。