gpt4 book ai didi

asp.net - 偶尔出现SqlException : Timeout expired

转载 作者:行者123 更新时间:2023-12-02 01:56:32 24 4
gpt4 key购买 nike

我的服务器上正在运行应用程序。这个应用程序的问题是,每天我都会遇到近 10-20 次 System.Data.SqlClient.SqlException 超时已过期的情况。操作完成之前超时时间已过,或者服务器仅响应我的 SP 之一。这是我的 SP,

            ALTER PROCEDURE [dbo].[Insertorupdatedevicecatalog] 
(@OS NVARCHAR(50)
,@UniqueID VARCHAR(500)
,@Longitude FLOAT
,@Latitude FLOAT
,@Culture VARCHAR(10)
,@Other NVARCHAR(200)
,@IPAddress VARCHAR(50)
,@NativeDeviceID VARCHAR(50))
AS
BEGIN

DECLARE @OldUniqueID VARCHAR(500) = '-1';
SELECT @OldUniqueID = [UniqueID] FROM DeviceCatalog WHERE (@NativeDeviceID != '' AND [NativeDeviceID] = @NativeDeviceID);

BEGIN TRANSACTION [Tran1]
BEGIN TRY
IF EXISTS(SELECT 1 FROM DeviceCatalog WHERE [UniqueID] = @UniqueID)
BEGIN
UPDATE DeviceCatalog
SET [OS] = @OS
,[Location] = geography::STGeomFromText('POINT(' + CONVERT(VARCHAR(100 ), @Longitude) + ' ' + CONVERT(VARCHAR(100), @Latitude) + ')', 4326)
,[Culture] = @Culture
,[Other] = @Other
,[Lastmodifieddate] = Getdate()
,[IPAddress] = @IPAddress
WHERE [UniqueID] = @UniqueID;
END
ELSE
BEGIN
INSERT INTO DeviceCatalog
([OS]
,[UniqueID]
,[Location]
,[Culture]
,[Other]
,[IPAddress]
,[NativeDeviceID])
VALUES (@OS
,@UniqueID
,geography::STGeomFromText('POINT(' + CONVERT(VARCHAR(100) ,@Longitude) + ' ' + CONVERT(VARCHAR(100), @Latitude) + ')', 4326)
,@Culture
,@Other
,@IPAddress
,@NativeDeviceID);
IF(@OldUniqueID != '-1' AND @OldUniqueID != @UniqueID)
BEGIN
EXEC DeleteOldDevice @OldUniqueID, @UniqueID;
END
END
COMMIT TRANSACTION [Tran1];
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [Tran1];
DECLARE @ErrorNumber nchar(5), @ErrorMessage nvarchar(2048);
SELECT
@ErrorNumber = RIGHT('00000' + ERROR_NUMBER(), 5),
@ErrorMessage = @ErrorNumber + ' ' + ERROR_MESSAGE();
RAISERROR (@ErrorMessage, 16, 1);
END CATCH
END

这个SP有什么问题吗?为什么我只在这个 SP 中遇到超时异常?这是堆栈跟踪,

System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at App.Classes.DBLayer.Execute(SqlCommand command, Boolean executeNonQuery)
at App.Helpers.SQLHelper.GetResult(List`1 parameters, Boolean storedProcedure, String commandText, ResultType type)
at App.Helpers.SQLHelper.ExecuteNonQuery(List`1 parameters, Boolean storedProcedure, String commandText)
at App.Services.DeviceCatalogService.InsertOrUpdateDeviceCatalog(DeviceCatalog deviceCataLog)
at WebApplication1.Handlers.RegisterDevice.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

最佳答案

您需要在服务器端对此进行调查,以了解执行超时的原因。注意服务器没有超时,超时是 SqlCommand.CommandTimeout 上默认30秒导致的.

一个好的资源是 Waits and Queues ,这是一种诊断 SQL Server 性能瓶颈的方法。根据超时的实际原因,可以采取适当的措施。您必须首先确定您正在处理的是执行缓慢(糟糕的计划)还是阻塞。

如果我大胆猜测一下,我会说 IF EXISTS... UPDATE 的不健康模式是根本原因。这种模式是不正确的,会导致并发下的失败。两个并发事务执行 IF EXISTS同时都会得出相同的结论,并且尝试 INSERTUPDATE 。根据数据库中现有的约束,您可能会遇到死锁(幸运的情况)或丢失写入(不幸的情况)。然而,只有适当的调查才能揭示真正的根本原因。可能是完全不同的东西,比如 auto-growth events .

您的过程也错误地处理了 CATCH block 。您必须始终检查 XACT_STATE() 因为在 CATCH block 运行时事务可能已经回滚。也不清楚您对命名事务的期望,这是我看到的一个常见错误,通常与混淆命名事务和保存点有关。对于正确的模式,请参阅 Exception Handling and Nested Transactions .

编辑

以下是调查此问题的可能方法:

  1. 更改相关 CommandTimeout 到 0(即无限)。
  2. 启用 blocked process threshold ,设置为30秒(之前的CommandTimeout)
  3. 在探查器中监控 Blocked Process Report Event
  4. 开始工作
  5. 查看探查器是否生成任何报告事件。如果确实如此,他们将查明原因。

如果超时是由阻塞引起的,则每次超时时,这些操作都会导致“阻塞进程报告”事件。如果阻塞是由 live-lock 引起的,您的应用程序将继续等待,直到阻塞被移除。然后它将永远等待。

关于asp.net - 偶尔出现SqlException : Timeout expired,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16917107/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com