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