老问题:“已有打开的与此连接相关联的 DataReader,必须首先将它关闭”,高手请进

xijupony 2007-06-12 05:24:06
在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都有关闭掉。
谢谢
...全文
979 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
phommy 2007-06-13
  • 打赏
  • 举报
回复
虽然结掉了,还是说下我用DataReader的原则,就是只在using里声明DataReader变量~ 关闭 释放连接什么都可以不用手动做的
flyingfz 2007-06-12
  • 打赏
  • 举报
回复
mark
xijupony 2007-06-12
  • 打赏
  • 举报
回复
sp1234(asp.net不是一个语言,是一个操作系统) 和it_mpf(初级)两位朋友能说清除些么?谢谢
it_mpf 2007-06-12
  • 打赏
  • 举报
回复
楼主的代码危险度较高.....你这样写是在虐待你的数据库
xijupony 2007-06-12
  • 打赏
  • 举报
回复
我想我得解释一下为什么我这个必须使用static
是因为在XXXX.SqlConn这个类中,我是想不需要new这个对象就能够使用到里边的方法
  • 打赏
  • 举报
回复
声明 SqlConnection 类型的对象并且执行它的 open 方法并不代表着物理地创建了数据库连接,一定要记住 SqlConnection 是自动管理连接池的。对于SqlConnection 编程,如果忽略连接池的存在,就会作出担心天塌下来式的多余设计。
zjysky 2007-06-12
  • 打赏
  • 举报
回复
深入学习
  • 打赏
  • 举报
回复
conn.Open(); --> conn1.Open();

声明两个SqlConnection 对象有多少性能代价?首先区分什么是大事小事,总体代价会成百倍地减少。
xijupony 2007-06-12
  • 打赏
  • 举报
回复
编译时提示:
“非静态的字段、方法或属性“XXXX.SqlConn.getConn()”要求对象引用”

。。。。
不是我想用static,是不得不用,不然没法编译下去。
像类似的函数结构,仅仅是public还不够吗?
北京的雾霾天 2007-06-12
  • 打赏
  • 举报
回复
当一个页面需要打开好几十个DataReader
---------------
怎么会是这样的呢,如果数据来自不同的表,最好使用多个Select语句拼到一起来使用,你这样频繁的和数据库打交道就是问题了.

对于一个DataReader来说,可以同时打开不同的多个表.再有应该考虑下使用DataAdapter来把数据填充到DataTable或DataSet中来减少和数据库的交互!
  • 打赏
  • 举报
回复
同意hbxtlhx(平民百姓-自已动手,丰衣足食)所说。

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

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

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

相反,你自己发明所谓共享数据库物理连接的手段,即使写的再好,能逃得出数据库连接池的框架吗?你只是因为不知道连接池为何物,而努力“重复发明汽车轮子”,并且发明出来的东西还不能用。
Netken 2007-06-12
  • 打赏
  • 举报
回复
tCmd.ExecuteReader(CommandBehavior.CloseConnection); 处添加一个参数试试,你返回的DataReader被外部使用完毕后会自动关闭Connection的。

还有 XXDataReader 方法最好别用静态的。

public SqlDataReader XXDataReader(string tSQL, SqlConnection tConn)
{
//最好先赋初值为null
SqlDataReader tReader = null;
SqlCommand tCmd = new SqlCommand(tSQL, tConn);
tReader = tCmd.ExecuteReader(CommandBehavior.CloseConnection);
tCmd.Dispose();
return tReader;
}
xijupony 2007-06-12
  • 打赏
  • 举报
回复
谢谢ydsunny(在路上)
xijupony 2007-06-12
  • 打赏
  • 举报
回复
回hbxtlhx(平民百姓-自已动手,丰衣足食)
觉得SqlConnection 最好不要公用一个,最好在每一个函数中都声明一个新的,在使用完闭后再Close掉.

话虽如此,.Net说new一个Conn是不怎么浪费资源,但当一个页面需要打开好几十个DataReader时,还要不停的新建数据链接,就太费时了。这已经在我的程序中得到印证。最终我还是得只能使用一个Conn,没打开了DataReader后,我马上关闭,再去打开第二个,是可行的。
就算是没用一个DataReader就新建一个Conn,在并发时也还是会出现上述的问题。

不过还是要感谢您的参与。
北京的雾霾天 2007-06-12
  • 打赏
  • 举报
回复
net_lover(【孟子E章】)
谢谢孟老大,名人啊。
--------------------------
其本一字千金,从没有多余的费话,不像我,回复了一次还可能要再回复几次...
九章落地 2007-06-12
  • 打赏
  • 举报
回复
出错的地方每次都不一样,但都是在
SqlDataReader XXReader = XXDataReader(tSQL, meConn);
处。从页面执行的速度上来说,应该是两个用户同时运行到一处打开了DataReader的地方。
可按道理说,两个用户应该不会公用到一个Conn连接的。。

//很显然,就是在打开SqlDataReader的时候,有Conn连接还未关闭.楼主你定义Conn是Static静态的,系统只创建一个链接,两个用户当然会共用一个Conn连接.
如果楼主的程序里DataReader用得很多,那创建连接的方法就要去掉Static
public SqlConnection getConn()
{
if (XXOpenConn())
return Conn;
else
return null;
}
北京的雾霾天 2007-06-12
  • 打赏
  • 举报
回复
因为SqlServer会自动的来管理它的相同连接的连接池,所以即使建立一个新的连接也是从池中取出一个,而不是会占用很多资源,而且这样不会存在因连接不用而被超时的问题.
xijupony 2007-06-12
  • 打赏
  • 举报
回复
回 hbxtlhx(平民百姓-自已动手,丰衣足食)
这个我懂,我都是按您说的这么处理的。还有就是,当几个DataReader顺序运行时,是可以占用一个Conn的吧。
我现在的问题是单个用户访问不会出错,多个用户并发时才会出现错误。

net_lover(【孟子E章】)
谢谢孟老大,名人啊。
北京的雾霾天 2007-06-12
  • 打赏
  • 举报
回复
觉得SqlConnection 最好不要公用一个,最好在每一个函数中都声明一个新的,在使用完闭后再Close掉.
shilei831115 2007-06-12
  • 打赏
  • 举报
回复
dataReader千万不要 不释放阿,


会死人的
加载更多回复(3)

62,047

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧