久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

sql中怎么使用TRY/CATCH語句避免死鎖

192次閱讀
沒有評論

共計 2458 個字符,預計需要花費 7 分鐘才能閱讀完成。

這篇文章主要為大家展示了“sql 中怎么使用 TRY/CATCH 語句避免死鎖”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓丸趣 TV 小編帶領大家一起研究并學習一下“sql 中怎么使用 TRY/CATCH 語句避免死鎖”這篇文章吧。

死鎖是正常現象不可避免。發生死鎖會犧牲一個進程并回滾事務,SQL 不會自己重試,需要用 TRY/CATCH 和 WAITFOR 實現重試。具體方法如下
如何使用 TRY/CATCH 語句避免死鎖
現在,讓我們來使用 TRY/CATCH 語句修改代碼正文。(對于本示例,需要以 SQL Server 2005 版本運行代碼。)使用 TRY/CATCH 時,操作代碼和錯誤處理代碼是分開的。您應該將執行一個操作的代碼放在 TRY 語句塊中,將錯誤處理代碼放在 CATCH 語句塊中。如果 TRY 語句塊中的代碼執行失敗,代碼執行將跳到 CATCH 語句塊。(除了那些防礙整個批處理運行的錯誤(如,丟失對象),該方法幾乎適用于所有的錯誤。)

以下示例使用 TRY/CATCH 語句對前面使用的代碼進行了改寫。代碼標題相同,但是代碼正文不同:

BEGIN TRANSACTION
BEGIN TRY
  INSERT Authors VALUES
  (@au_id, @au_lname, , , , , , 11111 , 0)
  WAITFOR DELAY 00:00:05
  SELECT COUNT(*)  FROM Authors
  COMMIT
END TRY
BEGIN CATCH
  SELECT ERROR_NUMBER() AS ErrorNumber
  ROLLBACK
END CATCH;
SELECT @@TRANCOUNT AS @@Trancount
現在,在連接到 SQL Server 2005 的并列窗口中運行這些代碼,在此之前您需要確認已經刪除了 authors 表格中任何可能阻止插入操作的數據;或者,您可以使用前置 DELETE 語句。

兩個窗口返回的 @@TRANCOUNT 級別都為 0,這表明仍然發生了死鎖,但 TRY/CATCH 語句捕獲了這次發生的死鎖。死鎖犧牲品的批處理沒有再次中止,可在它的輸出結果中看到錯誤:

ErrorNumber
———–
1205
@@Trancount
———–
0
您應該已經發現 TRY/CATCH 語句具有的威力了。因為死鎖錯誤能夠為 CATCH 語句塊所捕獲,所以批處理將不再中止,T-SQL 代碼也能繼續執行。對于死鎖犧牲品而言,死鎖錯誤 1205 將代碼放入 CATCH 語句塊 — 在這里您可以使用新的錯誤處理函數瀏覽死鎖錯誤。前置代碼僅使用 ERROR_NUMBER() 函數取代 @@ERROR 變量,您也可以使用 ERROR_MESSAGE()、ERROR_PROCEDURE()、ERROR_SEVERITY() 和 ERROR_STATE()。這些函數的功能一目了然,它們提供的功能比我們以往使用的更多。

請注意,這個前置 CATCH 語句塊包含一個 ROLLBACK。這樣做的原因是,即使捕獲了死鎖錯誤,事務也不會回滾。事務仍然要失敗,但是,現在您有責任在 TRY/CATCH 語句中回滾事務。那么,區別在哪里?盡管您不能使事務繼續進行,但是您能夠重試事務!

在 TRY/CATCH 語句中進行重試

在 SQL Server 2000 的 T-SQL 中,錯誤 1205 令人沮喪之處是它提供的建議:“Rerun the transaction.”問題是,至少在 SQL Server 2000 的 T-SQL 中,您不能做到這一點。但是,由于 SQL Server 2005 的 TRY/CATCH 為我們提供了捕獲死鎖錯誤的方法,現在,重試事務是可能實現的。

以下代碼正文說明了一種執行重試操作的方法。這段代碼仍然使用與前面相同的標題:

DECLARE @Tries tinyint
SET @Tries = 1
WHILE @Tries = 3
BEGIN
  BEGIN TRANSACTION
  BEGIN TRY
    INSERT Authors VALUES
      (@au_id, @au_lname, , , , , , 11111 , 0)
    WAITFOR DELAY 00:00:05
    SELECT * FROM authors WHERE au_lname LIKE Test%
    COMMIT
    BREAK
  END TRY
  BEGIN CATCH
    SELECT ERROR_NUMBER() AS ErrorNumber
    ROLLBACK
    SET @Tries = @Tries + 1
    CONTINUE
  END CATCH;
END
這段代碼的功能是通過一個 WHILE 循環添加一個重試操作。我將重試次數設置為 3,重試次數是可以配置的。至少我們現在有了一種在 T-SQL 內重試一個死鎖犧牲品代碼的方法 — 這是我們過去一直無法做到的。

但是,需要注意整個事務是在 WHILE 循環內進行的 — 而不是在循環外部。因此執行循環時,事務不僅在每個循環體內部開始,而且也在其中結束 — 不是 TRY 語句塊執行完畢,返回一個 COMMIT,就是 CATCH 語句塊執行,返回一個 ROLLBACK。如果 TRY 成功,TRY 語句塊將以一個 BREAK 語句結束,退出 WHILE 循環。否則,CATCH 語句塊將重試計數器加 1,以一個 CONTINUE 語句結束本次循環,重新執行下次 WHILE 循環。事實上,您有實現重試事務的代碼 — 就像錯誤 1205 告訴我們做的那樣。但現在,重試操作完全在 T-SQL 內部完成。

sql Server 2005 也提供幫助解決死鎖問題的其他方法,例如 SNAPSHOT ISOLATION 級別和用于 READ COMMITTED 的新選項(稱為 READ COMMITTED SNAPSHOT)。然而,這一事實 — 現在,通過 SQL Server 2005,您能夠對事務進行編碼并捕獲死鎖錯誤(并重試它們)— 已經意味著您擁有一個可任意支配、功能更加強大的工具。 

以上是“sql 中怎么使用 TRY/CATCH 語句避免死鎖”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注丸趣 TV 行業資訊頻道!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-25發表,共計2458字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 鄂州市| 麻城市| 樟树市| 安溪县| 循化| 桦川县| 凤山市| 渝中区| 乌鲁木齐县| 灯塔市| 合水县| 肃南| 高清| 疏勒县| 建德市| 蒲城县| 镇坪县| 仪征市| 孝昌县| 南溪县| 那坡县| 内丘县| 荔波县| 友谊县| 平利县| 霍邱县| 梧州市| 江源县| 五指山市| 车致| 富阳市| 沙田区| 咸丰县| 霍城县| 荃湾区| 濮阳县| 邮箱| 丹棱县| 宜君县| 阿克苏市| 郴州市|