2010-02-16 107 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