最近,我们的 QA 团队在我们的一个应用程序中报告了一个非常有趣的错误。我们的应用程序是一个基于 C# .Net 3.5 SP1 的应用程序,它与 SQL Server 2005 Express Edition 数据库交互。
按照设计,该应用程序被开发用于检测数据库离线场景,如果是这样,则等待数据库在线(通过及时重试连接),一旦在线,重新连接并恢复功能。
我们的 QA 团队所做的是,当应用程序从数据库中检索大量数据时,停止数据库服务器,等待一段时间并重新启动数据库。一旦数据库重新启动,应用程序将重新连接到数据库而没有任何问题,但它开始不断报告异常“找不到带有句柄 x 的准备好的语句”(x 是某个数字)。
我们的应用程序正在使用准备好的语句,并且它已经设计为在应用程序重新连接到数据库时再次对所有 SqlCommand 对象调用 Prepare() 方法。例如,
在应用程序启动时,
SqlCommand _commandA = connection.CreateCommand();
_commandA.CommandText = @"SELECT COMPANYNAME FROM TBCOMPANY WHERE ID = @ID";
_commandA.CommandType = CommandType.Text;
SqlParameter _paramA = _commandA.CreateParameter();
_paramA.ParameterName = "@ID";
_paramA.SqlDbType = SqlDbType.Int;
_paramA.Direction = ParameterDirection.Input;
_paramA.Size = 0;
_commandA.Parameters.Add(_paramA);
_commandA.Prepare();
之后,我们在此 _commandA 上使用 ExceuteReader(),并在应用程序的每个周期中使用不同的 @ID 参数值。
一旦应用程序检测到数据库脱机并重新联机,在重新连接到数据库时,应用程序只会执行,
_commandA.Prepare();
我们注意到另外两件奇怪的事情。1.上述情况发生在代码中的CommandType.Text类型命令。我们的应用程序也使用相同的逻辑来调用存储过程,但我们从来没有遇到过存储过程的这个问题。2. 到目前为止,无论我们在 Visual Studio 的 Debug 模式下尝试了多少不同的方法,我们都无法重现此问题。
提前致谢..