2013-04-23 57 views
0

我今天注意到我的應用程序出現了一些錯誤,它試圖在表中插入一條記錄,並且由於暫時的網絡延遲而收到超時錯誤。該應用程序的編碼是爲了識別這種情況,並在這種情況下重試,而這種情況很順利。但是在重試時,它經歷了主鍵違例 - 主要是因爲第一個插入語句實際上已經完成,但是發生了超時而將響應傳送回客戶端。應用程序認爲主鍵違規是嚴重的邏輯錯誤,不應該發生,因此會中止整個過程。什麼層應該負責處理超時到SQL Server的邏輯負責?

對我來說問題是什麼層在邏輯上應該負責處理這類事情?理想情況下,我會認爲SQL客戶端庫(在本例中爲ADO.NET 4.0)應該這樣做,但它沒有我知道的自動重試機制。鑑於它沒有,似乎有可能在SQL客戶端庫的低級別包裝器,但我不知道如果沒有更多的訪問有關超時發生時間的信息,它可以被寫入:例如,在這種例子中,可能的做法是:a)INSERT語句只是使用自動遞增鍵插入新記錄,因此在超時後重試會導致插入重複記錄,或b)主鍵違規事實上是一個邏輯錯誤,並且如果沒有發生超時,初始嘗試插入一條記錄會產生相同的違規行爲

OTOH我確信我能想到的例子是否只能確定是否重試在應用程序級別(尤其是如果它需要用戶確認的話)。

我實際上有些驚訝我以前從來沒有見過這個特別的錯誤序列,因爲它在實踐中似乎很有可能。

回答

0

顯然這個特定問題的解決方案是使用'SET XACT_ABORT ON'。 據報道,如果客戶機上存在運行時錯誤,則會導致SQL Server回滾語句。我很好奇爲什麼它不是實際的默認行爲。

+0

'XACT_ABORT'實際上與客戶端遇到運行時錯誤無關。它與語句的執行環境遇到運行時錯誤有關。如果事務遇到運行時錯誤(在服務器上),那麼它將中止並回滾整個事務。您的客戶端庫(如.NET中包含的庫)會由於缺陷而遇到運行時錯誤,並且SQL Server上的事務仍可能成功。 「XACT_ABORT」很可能不是默認的簡單符合OLE DB常見做法;原因可能是因爲一些性能的提升。 – 2014-02-19 04:22:26

0

IDENTITY財產does not guarantee uniqueness,永遠。這意味着當您在給定的表上併發INSERT語句時,您的自動遞增值可能會在多個活動事務中複製。

解決此問題的一種方法是在開始交易之前發出SET TRANSACTION ISOLATION LEVEL SERIALIZABLE聲明。這將防止衝突的插入,意味着沒有兩個插入可以並行執行。

另一種更常見的方式是簡單地重新嘗試您的事務或語句,直到您沒有收到主鍵違例爲止。這應該只在您不執行身份插入並且讓SQL Server處理主鍵值並且它是自動遞增的情況下完成。

另一種以某種可接受的方式處理此問題的方法是使用UNIQUEIDENTIFIER類型的主鍵。這些幾乎保證是獨一無二的。你可以在很長一段時間後,開始接收重複;這將需要與重試相同的邏輯,並且會丟失主鍵索引的物理佈局優化。這是一個替代或註釋,而不是建議。

總而言之,如果你想處理錯誤和你使用的是SQL Server 2012中,你可以簡單地使用下面的模板,以確保您的交易是適當的回滾和錯誤移動到表面:

BEGIN 
    SET NOCOUNT ON; 
    SET XACT_ABORT OFF; 

    BEGIN TRANSACTION; 
     BEGIN TRY 
      -- Do stuff here 
     END TRY 
     BEGIN CATCH 
      ROLLBACK TRANSACTION; 
      THROW; 
     END CATCH 

    COMMIT TRANSACTION; 
END 

另請注意,此模板不適用於存儲過程的嵌套調用,如果以該方式使用,將回滾整個過程鏈。

編輯

由於您使用ADO .NET,您可以禁用連接池和照顧連接管理自己。如果一個連接超時池化關閉,它會在服務器端發生故障並銷燬事務,導致回滾。

+0

雖然我沒有說我使用了IDENTITY,但我的交易一次只能插入一條記錄。服務器端沒有發生錯誤 - 它在等待響應時位於客戶端。服務器無法確定客戶端在最終提交更改時沒有拋出異常,所以我沒有看到任何基於服務器的解決方案是如何工作的。真的,我能看到的唯一解決方案是在超時異常之後檢查客戶端是否實際插入了記錄。 – 2014-02-19 00:00:21

+0

@DylanNicholson很難確定你的過程失敗的是什麼點。你提到了一個超時錯誤,然後重試了一次,但指出即使使用了自動遞增鍵,也會遇到一個主鍵衝突,因此會出現'IDENTITY'列或某種設計,其中應用程序負責自動遞增。在後一種情況下,我會爭辯說你應該在服務器端放置自動遞增行爲。據說,我指出了許多不同的解決方案來從多個角度對付你的問題。 – 2014-02-19 04:13:16