我有一個 C# windows 服務正在通過呼叫寫入 SQL Server 2012 資料庫exec sp_executesql。
exec sp_executesql N'Insert into [table name redacted]
(trial.[field redacted],trial.[field redacted],trial.[Duration],trial.[Count],trial.[Step],trial.[Target],trial.[ResultData],trial.[SessionDateTime],trial.[field redacted],trial.[ModifiedOn],trial.[CreatedOn],trial.[field redacted],trial.[SerialNumber],trial.[Category],trial.[CreatedBy],trial.[ModifiedBy],trial.[Status],trial.[IsEnabled],trial.[IsImmutable],trial.[IsHidden],trial.[Ordinal],trial.[IconUrl],trial.[Url],trial.[DataName],trial.[DisplayName],trial.[Description])
values (@field redacted_0,@field redacted_0,@Duration_0,@Count_0,@Step_0,@Target_0,@ResultData_0,@SessionDateTime_0,@field redacted_0,@ModifiedOn_0,@CreatedOn_0,@field redacted_0,@SerialNumber_0,@Category_0,@CreatedBy_0,@ModifiedBy_0,@Status_0,@IsEnabled_0,@IsImmutable_0,@IsHidden_0,@Ordinal_0,@IconUrl_0,@Url_0,@DataName_0,@DisplayName_0,@Description_0)',
N'@field redacted_0 uniqueidentifier,@field redacted_0 nvarchar(4000),@Duration_0 bigint,@Count_0 int,@Step_0 nvarchar(4000),@Target_0 nvarchar(4000),@ResultData_0 nvarchar(4000),@SessionDateTime_0 datetime,@field redacted_0 uniqueidentifier,@ModifiedOn_0 datetime,@CreatedOn_0 datetime,@field redacted_0 uniqueidentifier,@SerialNumber_0 nvarchar(8),@Category_0 nvarchar(4000),@CreatedBy_0 nvarchar(11),@ModifiedBy_0 nvarchar(11),@Status_0 nvarchar(6),@IsEnabled_0 bit,@IsImmutable_0 bit,@IsHidden_0 bit,@Ordinal_0 int,@IconUrl_0 nvarchar(4000),@Url_0 nvarchar(4000),@DataName_0 nvarchar(4000),@DisplayName_0 nvarchar(12),@Description_0 nvarchar(4000)',@field redacted_0='BB52C791-28BC-EC11-BE10-E884A50CE990',@field redacted_0=NULL,@Duration_0=0,@Count_0=0,@Step_0=NULL,@Target_0=N'',
@ResultData_0=NULL,@SessionDateTime_0='2022-04-19 17:57:23',@field redacted_0='F626F234-0AC0-EC11-BE11-E884A50CE990',@ModifiedOn_0='2022-04-19 17:59:15.590',@CreatedOn_0='2022-04-19 17:59:15.590',@field redacted_0='EEFB196C-0AC0-EC11-BE11-E884A50CE990',@SerialNumber_0=N'00000057',@Category_0=NULL,@CreatedBy_0=N'John Stamos',@ModifiedBy_0=N'John Stamos',@Status_0=N'Normal',@IsEnabled_0=1,@IsImmutable_0=0,@IsHidden_0=0,@Ordinal_0=0,@IconUrl_0=NULL,@Url_0=NULL,@DataName_0=NULL,@DisplayName_0=N'Mobile Trial',@Description_0=NULL
通常,插入幾乎是瞬時的。有時,可能 1000 次中的 1 次會導致錯誤
Win32Exception:等待操作超時
我對 SQL Server 資料庫管理一點也不流利,我的搜索導致我進行了許多讀取修復,包括exec sp_updatestats和with (NOLOCK)修復,但我不確定在處理插入時如何解決這個問題,甚至不知道如何弄清楚我正在進入這種狀態。我們目前根本沒有(有意地)使用事務,所以應該有最少的鎖定。我們在表中插入了 480 萬行,并且它確實具有指向另一個只有 116K 行的表的外鍵。
這是表模式。我正在尋找有關如何確定導致此問題的原因的幫助。這只是在生產中發生,當然是間歇性的,因此故障排除一直很困難。

提前致謝。
更新:根據@Charlieface 的建議,我在遇到超時時運行了查詢并得到了這些結果。

如何使用此資訊找出導致鎖定的原因?我猜等待命令很重要,但這是我迄今為止唯一的猜測。
更新 2:這是 SQLException(相對于 Win32Exception)
2022-04-20 16:00:47,861 [4] 錯誤 Net.ExceptionMarshallingErrorHandler - System.Data.SqlClient.SqlException (0x80131904):執行超時已過期。在操作完成之前超時時間已過或服務器沒有回應。---> System.ComponentModel.Win32Exception (0x80004005): System.Data.SqlClient.SqlConnection.OnError(SqlException 例外, Boolean breakConnection, Action'1 wrapCloseInAction) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning 的等待操作超時System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 在 System.Data.SqlClient.TdsParser.TryRun (TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 在 System.Data.SqlClient.SqlDataReader。
uj5u.com熱心網友回復:
從阻塞鏈腳本的結果可以看出,阻塞鏈的頭部狀態為AWAITING COMMAND. 這意味著它可能有一個未完成的交易,該交易在持有鎖的同時處于掛起狀態。在服務器決定斷開連接之前,所有其他事務都會在那些被鎖定的行或物件上阻塞。這導致超時。解決方案是不要增加命令或鎖定超時,因為這不能解決根本原因。
我建議您仔細查看觸發該命令的代碼。它可能有兩種使用事務的方式:
在同一個批處理或程序中使用服務器端
BEGIN TRAN和陳述句。COMMIT如果發生批處理中止錯誤,事務將一直掛起,直到連接關閉或重置。
但由于 ADO.Net 管理連接池的方式,直到連接被重用或 4 分鐘超時到期時才會發生這種情況。(這using與連接物件上的使用無關。)將客戶端事務與
SqlTransaction.BeginTransaction.如果發生例外,一條
using陳述句通常會確保成功回滾和釋放鎖。
但這有時不會成功,例如如果客戶端失去網路連接。
解決這兩個問題的方法是:
- 要始終
using在連接、事務、命令和讀取器物件上使用陳述句。如果客戶端發生例外,這將提供最大努力的回滾。 - 確保
XACT_ABORT設定為ON。這意味著服務器將始終在發生錯誤時回滾。
您可以將其作為批處理或程序的一部分執行,或者更好:將其設定為服務器范圍的默認值。
使用服務器端事務通常比客戶端事務好,因為在客戶端丟失網路連接的情況下,服務器將不知道回滾。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/461547.html
標籤:sql sql服务器 tsql sql-server-2012
