日期:2014-05-18  浏览次数:20564 次

老问题:“已有打开的与此连接相关联的 DataReader,必须首先将它关闭”,高手请进
在Asp.Net中,感觉SqlDataReader还是挺好用的。
但最近还是出现了这个问题。。
页面A有不少地方都使用到了这个对象,我都已经将它关闭了。单个用户进程访问这个页面时不会出现出错的提示。两个以上的用户同时刷新这个页面就出错了。
我的SqlConnection是在一个组件里调用的,组件例子如下:
namespace   XXXX
{
public   abstract   class   SqlConn
{
static   SqlConnection   Conn;
public   static   bool   XXOpenConn()
{
Conn   =   new   SqlConnection(ConfigurationSettings.AppSettings[ "ConnString "]);
if   (Conn.State   !=   ConnectionState.Open)
{
try
{
Conn.Open();
return   true;
}
catch(SqlException)
{
return   false;
}
}
return   true;
}
public   static   SqlConnection   getConn()
{
if   (XXOpenConn())
return   Conn;
else
return   null;
}
public   static   SqlDataReader   XXDataReader(string   tSQL,   SqlConnection   tConn)
{
SqlDataReader   tReader;
SqlCommand   tCmd   =   new   SqlCommand(tSQL,   tConn);
tReader   =   tCmd.ExecuteReader();
tCmd.Dispose();
return   tReader;
}
public   static   Hashtable   GetSysConfig()
{
string   tSQL   =   "select   A   from   s_config ";
Hashtable   configHT   =   new   Hashtable();
SqlConnection   meConn   =   getConn();
SqlDataReader   configReader   =   XXDataReader(tSQL,   meConn);
if   (configReader.Read())
{
configHT[ "A "]   =   configReader[ "A "].ToString();
}
else
{
configHT[ "A "]   =   " ";
}
configReader.Close();
meConn.Close();
return   configHT;
}
}
}
以上是组件调用Conn已经一些DataReader的方法。。
外部的页面基本上是公用一个Conn连接,有同时使用到多个DataReader的我都会新开一个Conn连接,Read之后也都关闭了。
现在问题是单个用户访问,页面不会出错,多个用户同时打开,就会出错。请问这样的问题应该如何解决?

PS:已确认所有打开的DataReader都有关闭掉。
谢谢

------解决方案--------------------
你可以将static去掉试试
------解决方案--------------------
DataReader独占一个Connection,如果同时再有其它的方法使用Connection则要么关闭DataReader的Connection,要么再建立一个新的.
------解决方案--------------------
出错的地方每次都不一样,但都是在
SqlDataReader XXReader = XXDataReader(tSQL, meConn);
处。从页面执行的速度上来说,应该是两个用户同时运行到一处打开了DataReader的地方。
可按道理说,两个用户应该不会公用到一个Conn连接的。。

//很显然,就是在打开SqlDataReader的时候,有Conn连接还未关闭.楼主你定义Conn是Static静态的,系统只创建一个链接,两个用户当然会共用一个Conn连接.
如果楼主的程序里DataReader用得很多,那创建连接的方法就要去掉Static
public SqlConnection getConn()
{
if (XXOpenConn())
return Conn;
else
return null;
}

------解决方案--------------------
同意hbxtlhx(平民百姓-自已动手,丰衣足食)所说。

连接池本来就是为了共享数据库连接使用的,因此一下这两段:

string connStr=ConfigurationSettings.AppSettings[ "ConnString "];
using(SqlConnection conn1=new SqlConnection(connStr))
{
conn.Open();
..............
}
...............
using(SqlConnection conn2=new SqlConnection(connStr))
{
conn2.Open();
..............
}

完全可以看成可以自动共享数据库物理连接的。实际上,当着这两段在不同的地方,也可以看成是可以自动共享的。

相反,你自己发明所谓共享数据库物理连接的手段,即使写的再好,能逃得出数据库连接池的框架吗?你只是因为不知道连接池为何物,而努力“重复发明汽车轮子”,并且发明出来的东西还不能用。