簡體   English   中英

我可以使用C#鎖來防止Web應用程序中的SQL Server死鎖嗎?

[英]Can I use C# locks to prevent SQL Server deadlocks in my web application?

我正在使用C#在Visual Studio 2010中編寫Web應用程序。 該Web應用程序執行復雜的SQL Server 2008語句,如果一次同時調用同一.aspx頁不止一次,則有時會導致死鎖。 提出的解決方案是使用SQL Server手段來防止這些死鎖,但是我的問題是我不太了解它,對於C#來說這不是事實,我知道得更好。

所以我想知道,使用ASP.NET頁中的鎖(或C#中的鎖,或名為互斥鎖的Windows)對我有什么不利之處,而不是通過SQL Server進行鎖定以防止這些死鎖?

PS。 該SQL Server數據庫僅由該Web應用程序使用。

編輯:以下是執行SQL語句的C#代碼:

int iNumRows = 0;

using (SqlConnection cn = new SqlConnection(strConnection))
{
    cn.Open();

    using (SqlCommand cmd = new SqlCommand(strSQL, cn))
    {
        //Use C# lock here
        iNumRows = Convert.ToInt32(cmd.ExecuteScalar());
        //Release C# lock here
    }
}

這是一個SQL示例(實際上是由C#腳本動態組成的):

SET XACT_ABORT ON;
BEGIN TRANSACTION;

DELETE FROM [dbo].[t_Log_2] 
      WHERE [idtm]<'2011-03-12 08:41:57';

WITH ctx AS(
     SELECT MIN([idtm]) AS mdIn, 
            MAX([odtm]) AS mdOut 
           FROM [dbo].[t_Log_2] 
          WHERE [type] = 0 
            AND [state] = 0 
            AND [huid] = N'18ef4d56-6ef3-906a-a711-88d1bd6ab2d4' 
            AND [odtm] >= '2013-03-11 06:33:32' 
            AND [idtm] <= '2013-03-11 06:43:12' 
           ) 
INSERT INTO [dbo].[t_Log_2] 
([oid],[idtm],[odtm],[type],[state],[huid],
 [cnm],[cmdl],[batt],[dvtp0],[dvtp1]) 
SELECT 
    2, 
    CASE WHEN mdIn IS NOT NULL 
          AND mdIn < '2013-03-11 06:33:32' 
         THEN mdIn 
         ELSE '2013-03-11 06:33:32' 
         END,
    CASE WHEN mdOut IS NOT NULL 
          AND mdOut > '2013-03-11 06:43:12' 
         THEN mdOut 
         ELSE '2013-03-11 06:43:12' 
         END,
    0,
    0,
    N'18ef4d56-6ef3-906a-a711-88d1bd6ab2d4',
    null,
    null,
    0,
    1,
    null 
FROM ctx 

SELECT ROWCOUNT_BIG()

DELETE FROM [dbo].[t_Log_2] 
      WHERE [type] = 0 
        AND [state] = 0 
        AND [huid] = N'18ef4d56-6ef3-906a-a711-88d1bd6ab2d4' 
        AND [odtm] >= '2013-03-11 06:33:32' 
        AND [idtm] <= '2013-03-11 06:43:12' 
        AND [id] <> SCOPE_IDENTITY()

DELETE FROM [dbo].[t_Log_2] 
      WHERE [type] = 0 
        AND [huid] = N'18ef4d56-6ef3-906a-a711-88d1bd6ab2d4' 
        AND [idtm] >= (SELECT [idtm] FROM [dbo].[t_Log_2] 
                                    WHERE [id] = SCOPE_IDENTITY()) 
        AND [odtm] <= (SELECT [odtm] FROM [dbo].[t_Log_2] 
                                    WHERE [id] = SCOPE_IDENTITY()) 
        AND [id] <> SCOPE_IDENTITY() 

;WITH ctx1 AS( 
     SELECT [idtm] AS dI 
       FROM [dbo].[t_Log_2] 
      WHERE [id] = SCOPE_IDENTITY() 
             )
UPDATE [dbo].[t_Log_2] 
        SET [odtm] = ctx1.dI 
       FROM ctx1 
      WHERE [id] <> SCOPE_IDENTITY() 
        AND [type] = 0 
        AND [huid] = N'18ef4d56-6ef3-906a-a711-88d1bd6ab2d4' 
        AND [idtm] < ctx1.dI 
        AND [odtm] > ctx1.dI 

;WITH ctx2 AS(
     SELECT [odtm] AS dO 
       FROM [dbo].[t_Log_2] 
      WHERE [id] = SCOPE_IDENTITY() 
             ) 
UPDATE [dbo].[t_Log_2] 
        SET [idtm] = ctx2.dO 
       FROM ctx2 
      WHERE [id] <> SCOPE_IDENTITY() 
        AND [type] = 0 
        AND [huid] = N'18ef4d56-6ef3-906a-a711-88d1bd6ab2d4' 
        AND [idtm] < ctx2.dO 
        AND [odtm] > ctx2.dO 

COMMIT TRANSACTION;
SET XACT_ABORT OFF

使用ASP.NET頁中的鎖(或C#或Windows中稱為互斥鎖的鎖)而不是通過SQL Server進行鎖定以防止這些死鎖的缺點是什么?

不會造成死鎖,而是會導致死鎖。

當等待圖包含一個周期(A在B上等待,B在A上等待)時,將發生死鎖。 SQL Server定期檢查所有等待圖並查找周期。 當檢測到一個這樣的周期時,通過選擇受害者並中止其交易來中斷該周期。

如果將其中一些鎖移出SQL Server控制的領域,即。 在進程互斥體,關鍵部分,C#事件或任何其他情況下,仍將發生等待圖循環,但是現在該循環將通過應用程序完成,因此SQL Server將無法檢測到它(A等待SQL中的B,但是B等待A在應用中)。 由於死鎖監視器不會看到周期,因此它將不會運行死鎖解析算法(選擇受害者,中止其事務),並且死鎖將永遠保持下去。 恭喜,現在您的應用程序只是掛起,而不是引發死鎖異常!

您不必信服我的話,這個問題已經使其他經驗豐富的人煩惱了,並且學到了艱辛的方法,但是幸運的是寫了此書,以便您可以學習簡單的方法。 您正在閱讀的這個站點就是一個例子

了解問題后,解決SQL Server中的死鎖就相當容易了。 如果您捕獲並附加死鎖圖 (XML,而不是圖片!)以及表的確切定義,也許我們可以提供幫助。 las, 您已經忽略了這樣的要求,所以我想唯一要問的問題是您是否還想要繩子?

沒有足夠的細節,找不到真正導致死鎖的位置,我可以猜測可能是由於鍵范圍導致了死鎖,這意味着死鎖發生在表t_log_2的索引上,因為您具有刪除和更新功能,所以它們肯定不是發生在同一行上,但它們可以發生在同一鍵范圍上,或者一個進程可以容納A范圍,請求B范圍,而另一個進程可以容納B范圍並請求A范圍。 您可以使用SQL事件探查器跟蹤死鎖並查看死鎖的確切位置。 或者,簡單地說,如果它不會對您的性能造成太大影響,則可以將事務隔離級別設置為[可重復讀取]甚至[可序列化]。


SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
....
BEGIN TRANSACTION
....

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM