零星的ASP.NET数据错误:“找不到表0”

时间:2010-02-16 22:10:27

标签: asp.net sql-server dataset

在生产环境中部署了ASP.NET网站的新版本后,我每秒都会记录数十个数据错误,几乎总是出现错误“无法找到表0”。我们使用数据集并经常引用Table[0],虽然我理解在访问Table[0]之前检查表的数据集的防御性编码实践,但它在过去从未成为问题。某个页面将加载一秒钟,然后在下一个页面中丢失其中一个数据驱动的组件。只是看看这是否为任何人敲响了钟声。

更多细节:这次我使用了不同的构建服务器,虽然我想两者的编译器设置是相同的,但我很难想到有一个开关可以产生50%的我的数据库调用没有表回来。我还将项目切换到VS 2008 ,但是当我切换回VS 2005时我还原了所有这些更改。我注意到构建的程序集有一个新的 MyLibrary .XmlSerializers.dll ,它不习惯的地方,但我也无法想象这会造成所有麻烦。 (它也不会影响对 MyLibrary 的调用,或者至少不会超过任何其他时间。)

更新添加:我发现麻烦的构建是一个“Release”构建,其中工作构建被编译为“Debug”。可以解释它吗?

在这些更改修复之前回滚到构建。 (重新启动SQL Server,我们之前尝试的步骤没有。)

问题似乎也是基于负载的 - 这通过我们的集成和QA环境而没有问题,甚至我们的烟雾测试环境 - 指向生产数据的环境 - 在轻负载下也很好。

这是否具有您过去可能看到的任何特征?

6 个答案:

答案 0 :(得分:4)

碰到这个老问题是因为我们遇到了同样的问题,也许我们的解决方案会更深入地了解导致这个问题的原因。

基本上,这个问题发生在Windows服务中负载非常繁重的生产环境中,该服务使用多个线程同时处理多个作业(100个用户通过ASP.NET Web应用程序使用相同的DB,并且大约有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(dataset)将导致空数据集,从而导致“无法找到表0”。因为我们的服务会在失败时重试操作(读取作业列表)并且它总是会从池中获得相同的损坏连接,因此在重新启动之前它会因此错误而失败。

我们通过在异常上使用SqlConnection.ClearPool(连接)来删除此问题,以确保从池中丢弃此连接并重构应用程序,以便较少的线程同时访问相同的资源。

我不知道究竟是谁造成了这个问题,所以我不确定我们是否真的已经解决了这个问题,也许只是让它变得如此罕见,以至于它还没有再发生过。

答案 1 :(得分:2)

之前我已经准确地解决了这个错误信息。关键是基础数据方法吞噬超时异常。

你可能正在做这样的事情:

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

GetEmployeeDataSet正在吞噬一个异常,可能是一个超时异常,这就是为什么它只是偶尔发生 - 它发生在加载下。您需要执行以下操作来修复它:

  1. 修改底层代码以避免异常,但让它冒泡到下一级别,以便您可以正确识别它。
  2. 识别导致问题的查询,然后重写,重新索引,非规范化或抛出硬件问题。有关详情,请参阅此处:System.Data.SqlClient.SqlException: Timeout expired

答案 2 :(得分:1)

我见过类似的东西。我认为我们的问题与重新使用的失败会话有关(一旦会话对象失败,它就会进入状态不佳并且无法恢复。)我们通过增加会话池的内存并增加网络的频率来修复它。应用回收。

它也是由新版本引起的,乍一看似乎没有任何改变导致这种效果。然而,最终很明显,该计划的逻辑是打开和关闭更多的连接(可能比以前多20%)。这个小小的改变推动了我们之前配置的极限。

答案 3 :(得分:0)

您可能会检查SQL Server日志中的错误。或者,Web服务器事件日志。听起来你的连接池可能没有打开连接,或者你的数据库可能已经用完了。

答案 4 :(得分:0)

版本之间哪些数据库调用发生了变化?

错误显然告诉您,您的某个数据库调用有时没有返回任何数据;我无法想到代码/汇编问题会导致它的任何情况。

答案 5 :(得分:0)

在以非线程安全的方式使用nHibernate Sessions执行某些操作时,我看到过类似的内容。这可以解释为什么你只能在负载下看到它。需要看看你的代码猜测什么不是线程安全的。