2010-02-16 26 views
2

在生產環境中部署了一個ASP.NET站點的新版本後,我每秒都會記錄幾十個數據錯誤,幾乎總是出現錯誤「無法找到表0「。我們使用數據集並經常參考Table[0],雖然我理解在訪問Table[0]之前檢查表的數據集的防禦性編碼實踐,但過去從來不是問題。某個頁面會在一秒內加載正常,然後會丟失其中一個數據驅動組件。只要看看這是否爲任何人敲響了鐘聲。零星的ASP.NET數據錯誤:「找不到表0」

更多細節:我用不同構建服務器這個時候,雖然我想象中的編譯器設置上都一樣,我也很難認爲有一個開關,使我的數據庫調用50%來沒有桌子。我也切換該項目2008年VS,但隨後恢復所有的這些變化,當我切換回VS 2005年我注意到內置組件具有新在MyLibrary .XmlSerializers.dll,它沒有習慣了,但我也無法想象那會造成所有的麻煩。 (它也不會在電話落到在MyLibrary,或至少不超過任何其他的時間。)

更新補充:我發現麻煩的構建是一個「放」建設,工作構建被編譯爲「調試」。能解釋一下嗎?

在這些更改修復之前回滾到構建版本。 (重啓SQL Server,我們之前嘗試過的步驟沒有。)

麻煩也似乎是基於負載的 - 這通過我們的集成和質量保證環境而沒有問題,甚至我們的煙霧測試環境 - 指向生產數據的那個 - 在輕負載下很好。

這是否具有您可能在過去看到過的任何顯着特徵?

+0

看看我的答案在下面...這是一個很晚,所以你可能忽略了它,但我已經打了以前的錯誤信息,並以「硬殺死「我所描述的情況。 – 2011-01-28 18:13:13

回答

1

我見過類似的東西。我認爲我們的問題與重用失敗會話有關(一旦會話對象失敗,它將進入糟糕的狀態,無法恢復)。我們通過增加會話池的內存並增加Web的頻率來修復它應用回收。

它也是由一個新版本「引發」,在第一次臉紅似乎沒有任何改變,導致這樣的效果。然而,最終很明顯的是,該計劃的邏輯開啓和關閉了比以前更多的連接(可能多20%)。這一小小的變化推動了我們之前配置的極限。

+0

這很有趣 - 我不認爲這是我的「答案」,但我可以想象連接池是問題的一部分,因爲它很神祕。我會再看看代碼,看看有沒有什麼可疑的。 – dnord 2010-02-16 22:50:11

0

您可能會檢查SQL Server日誌中是否有錯誤。或者,Web服務器事件日誌。這聽起來像你的連接池可能沒有打開連接,或者你的數據庫可能不在。

+0

SQL Server錯誤日誌很乾淨。 你能想到任何改變連接池選項的編譯項目/程序集選項嗎?我不能。 – dnord 2010-02-16 22:22:49

0

哪些數據庫調用在版本之間發生了變化?

錯誤顯然告訴你你的數據庫調用有時並沒有返回任何數據;我想不出任何代碼/程序集問題會導致它的情況。

+0

增加了一個每晚報告,並更新了一個很少使用的SP。沒有核心功能被改變,並且錯誤似乎彈出了*數據庫可能被調用的每個可能的地方*,這就是爲什麼它對我來說很腥。 – dnord 2010-02-16 22:21:54

0

我以非線程安全的方式使用nHibernate會話進行某些操作時看到類似的情況。這可以解釋爲什麼你只能在負載下看到它。需要看你的代碼來猜測什麼是線程安全的。

4

顛覆這個老問題,因爲我們遇到了同樣的問題,也許我們的解決方案將給出更多的洞察是什麼原因造成的。

基本上,在使用多個線程同時處理多個作業的Windows服務中的負載很重的生產環境中會出現此問題(100個用戶通過ASP.NET Web應用程序使用相同的數據庫,並且大約有60個事務/ SQL Server 2000的舊硬件上)。

沒有變量共享,即連接重新打開,事務開始,操作執行,事務提交和連接關閉。

在重負載下有時以下例外情況之一:

NullReferenceException: Object reference not set to an instance of an 
object. 
at System.Data.SqlClient.SqlInternalConnectionTds.get_IsLockedForBulkCopy() 

System.Data.SqlClient.SqlException: 
The server failed to resume the transaction. Desc:3400000178 

New request is not allowed to start because it should come with valid transaction descriptor 

This SqlTransaction has completed; it is no longer usable 

看起來不知怎的,池內的連接已損壞,並與以前使用的事務保持關聯。此外,如果從池中檢索到這種連接,則sqlAdapter.Fill(數據集)會生成一個空數據集,從而導致「無法找到表0」。因爲我們的服務會在失敗時重試操作(讀取作業列表),並且它總是會從池中獲得相同的損壞連接,所以在重新啓動之前會出現此錯誤。

我們通過對異常使用SqlConnection.ClearPool(連接),以確保該連接從池中丟棄和調整應用程序,以更少的線程同時訪問相同的資源去除的問題。

我不知道究竟是誰造成了這個問題,所以我不確定我們是否真的解決了這個問題,也許只是讓它變得非常罕見而沒有再次發生。

2

我以前正好打過這個錯誤信息。關鍵是基礎數據方法是吞噬超時異常的

你可能做這樣的事情:

var table = GetEmployeeDataSet().Tables[0]; 

GetEmployeeDataSet是吞嚥異常,可能是超時異常,這就是爲什麼它只是偶爾發生 - 它發生在負載下。你需要做以下操作來解決它:

  1. 修改底層代碼無法吞嚥異常,而是讓它泡到一個新的水平,因此您可以正確識別它。
  2. 找出造成問題的查詢(一個或多個),然後改寫,重新索引,非規範化,或在問題扔硬件。看到這個更多的信息:System.Data.SqlClient.SqlException: Timeout expired
+0

謝謝;在我的情況下,代碼有幾個,所以這給了我一個開始尋找和掛鉤(增加異常塊)的好地方。 – 2014-10-20 23:37:23