SQL Server 返回空结果集(太忙?)

SQL Server 返回空结果集(太忙?)

我首先要表示歉意,我没有太多的信息可供参考,我只是希望寻求一些帮助来调试我的问题。

我有 5 个网站在装有 SQL Server 2008 RC2 的 Windows Server Web Edition 2008 计算机上运行。定期全部网站(不是同时)我会在我的 ASP.NET 2 网站中收到一些错误,提示Index was outside the bounds of the array.SQL 游标。这种情况发生在数据肯定存在的地方,如果不存在,我会收到更多错误。就好像 SQL 服务器由于某种原因无法返回结果一样。

我不知道如何开始调试,我似乎没有收到任何超时错误。我的问题是:

  1. 如何判断 SQL 服务器负载过大?我可以启用某些功能来跟踪负载吗?
  2. 如果我有日期和时间,我是否可以检查 SQL Server 上的某些日志以显示更多信息?如果可以,在哪里?

抱歉,描述得不太清楚;目前我没有更多相关信息。

编辑迄今为止的答案:

大多数情况下,相同的代码可以顺利运行。今天我设法通过创建一个无限循环并每次执行 SQL 查询来复制此问题,然后我尝试加载同一网站上的页面,结果又出现了此错误。我的意思是,光标返回为空,而它们本来不应该是空的。

編輯2 好吧,也许我解释得不太清楚。我明白越界错误是由编码引起的。我的意思是,这种情况会随机发生在 99.9% 的时间都有效的相同代码上。是的,代码会引发错误,但它首先不应该有一个空的结果集。以下是完整的堆栈跟踪(再次说明,此代码 99.9% 的时间都有效):

(我正在使用 Delphi.NET,所以 Borland 部分就是从这里来的)——还请注意,当它在内部清除自己的列表时会发生错误……

Borland.Vcl.TDBBufferList.FreeHGlobal(IntPtr Ptr) at 
Borland.Vcl.TCustomADODataSet.FreeRecordBuffer(IntPtr& Buffer) at 
Borland.Vcl.TDataSet.SetBufListSize(Int32 Value) at 
Borland.Vcl.TDataSet.CloseCursor() at 
Borland.Vcl.TDataSet.SetActive(Boolean Value) at 
Borland.Vcl.TDataSet.Close() at 
WebCommon.TStockItemIntf.@13$Initialise$GetPLPrice(TStockItemIntf Self, String CCode, String SkCode, String PLStr) at 
WebCommon.TStockItemIntf.@23$Initialise$FinalPrice(TStockItemIntf Self, $Unnamed205& $frame_TStockItemIntf.Initialise, TKosCompany Company, TKosStock SkItem, TStockPriceCalcType PLCalcOption) at 
WebCommon.TStockItemIntf.Initialise(TKosStock SkItem, STOCK_ITEM SkCatItem, TAssignStockOptions AssignOptions, HttpSessionState Session, String DefaultPriceList) at 
WebCommon.TKosDropInProducerP.@68$AssignStockItem$AssignStockObjLst(TKosDropInProducerP Self, $Unnamed206& $frame_TKosDropInProducerP.AssignStockItem, TKosStock SkItem, String DefaultPriceList) at 
WebCommon.TKosDropInProducerP.AssignStockItem(TStringList StockCodeList, CATEGORY Category, HttpSessionState Session, TAssignStockOptions AssignOptions) at 
RecentlyViewedShortList.TRecentlyViewedShortList.Page_Load(Object sender, EventArgs e) at 
System.Web.UI.Control.OnLoad(EventArgs e) at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Control.LoadRecursive() at 
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 

答案1

正如马丁指出的那样,这是一个.Net 错误。

您应该检查您的代码,它可能是任何东西,但我将给出一个伪代码中如何发生这种情况的例子:

Item[] myItems = new Item[sql.queryshot("select count(*) form myTable")];
int counter=0;

Cursor MyCursor = GetData();
foreach(Data data in MyCursor){
  myItems[counter] = new Item(data);
  counter++;
}

如果有人在数组 Item[] 初始化和 GetData() 方法之间插入一条记录,您将看到 Index 越界异常,因为您将越过数组的末尾。不过这种情况不会经常发生,因为这两个操作之间的时间很短。

如果服务器超载,您肯定会遇到其他错误,而不是这个错误。

答案2

此错误来自 .NET,与 SQL Server 完全无关。检查您的代码以确保您的数组定义正确。请记住,.NET 数组中也有一个 0 位置。如果您知道有 10 个帖子要从 SQL Server 读取,并且您将数组的长度设置为 10,则必须使用 0 - 9 而不是 1 -10,因为 10 会给您上述错误。因此根本不是 SQL Server 问题。

有很多方法可以追踪您的 SQL Server 是否负载过大或存在任何其他类型的问题,但这与您上面描述的问题无关。我建议https://dba.stackexchange.com/学习并阅读更多相关内容。

答案3

我已经设法找到了这个问题的原因(我认为)。

我可以绝对排除 SQL 服务器太忙,因为我已经在单独的 SQL 服务器实例上运行了一个网站,看看它是否有帮助,但问题仍然存在。

基本上,当我第一次编写网站的数据库连接代码时,我认为每次加载页面时创建并使用一个数据库连接会更好。现在我知道,这并不推荐,因为 SQL Server 的连接池无论如何都会处理这些连接。

当我使用此连接时,我认为保存记录缓冲区的 TList 有时会被更改,此时当我尝试访问存在但已被删除/更改的结果时,它会引发超出范围的异常。

在这一点上,我重写了我的数据库连接,现在使用本机的 .NET 连接,而不是 Delphi 的蹩脚改编。

相关内容