代码之家  ›  专栏  ›  技术社区  ›  dnord

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

  •  2
  • dnord  · 技术社区  · 14 年前

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

    更多细节:我用了 不同的生成服务器 这一次,虽然我认为两个编译器的设置是相同的,但我很难想象有一个开关可以使50%的数据库调用在没有表的情况下返回。我也 将项目切换到vs 2008 但当我切换回2005年的时候,所有的变化都恢复了。我注意到 已生成的程序集具有新的 MyLabor .xmlserializers.dll文件 在我不习惯的地方,但我也不能想象那会造成所有的麻烦。(它也不会落在 MyLabor 或至少不超过任何其他时间。)

    更新后添加:我发现麻烦的构建是一个“版本”构建,其中工作构建被编译为“调试”。 能解释一下吗?

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

    问题也似乎是基于负载的——这在我们的集成和质量保证环境中没有问题,甚至我们的冒烟测试环境——那个指向生产数据的环境——在轻负载下也很好。

    这是否具有您过去可能见过的任何事物的显著特征?

    6 回复  |  直到 12 年前
        1
  •  1
  •   Hogan    14 年前

    我也见过类似的东西。我认为我们的问题与重新使用失败的会话有关(一旦会话对象发生故障,它将进入不良状态,无法恢复)。我们通过增加会话池的内存和增加Web应用程序回收的频率来解决问题。

    它也是由一个新版本“引起”的,起初脸红似乎没有任何变化造成这种效果。然而,最终它变得清晰起来,程序的逻辑打开和关闭的连接比以前多了很多(可能多20%)。这一微小的变化推动了我们先前配置的限制。

        2
  •  4
  •   Arunas    13 年前

    因为我们遇到了同样的问题,也许我们的解决方案可以让我们更深入地了解是什么导致了这个问题。

    本质上,此问题发生在Windows服务的生产环境中,该环境的负载非常重,Windows服务使用多个线程同时处理多个作业(100个用户通过ASP.NET Web应用程序使用相同的数据库,在使用SQL Server 2000的较旧硬件上,每秒约有60个事务)。

    不共享变量,即重新打开连接、启动事务、执行操作、提交事务和关闭连接。

    在重载情况下,有时会出现以下例外情况之一:

    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(connection)on exception来消除这个问题,以确保从池中丢弃这个连接并重新构造应用程序,从而减少线程同时访问相同资源的次数。

    我不知道是谁造成了这个问题,所以我不确定我们是否真的解决了这个问题,也许只是使它如此罕见,还没有再次发生。

        3
  •  2
  •   Community Egal    7 年前

    我以前就曾和这个错误信息作过斗争。关键是基础数据方法是 吞咽超时异常。

    你可能会这样做:

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

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

    1. 修改底层代码以不吞咽异常,而是让它冒泡到下一个级别,这样您就可以正确地识别它了。
    2. 识别导致问题的查询,然后重写、重新索引、取消规范化或抛出硬件来解决问题。更多信息请参见: System.Data.SqlClient.SqlException: Timeout expired
        4
  •  0
  •   Josh    14 年前

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

        5
  •  0
  •   John    14 年前

    哪些数据库调用在版本之间发生了更改?

    很明显,错误是告诉您某个数据库调用有时不会返回任何数据;我想不出任何代码/程序集问题会导致此错误的情况。

        6
  •  0
  •   pdr    14 年前

    我在用非线程安全方式处理NHibernate会话时看到了类似的情况。这就解释了为什么你只能在负载下看到它。但需要看到您的代码来猜测什么不是线程安全的。