如何在分页的时候处理并发的情况

wwfgu00ing 2012-04-10 04:38:35
先有一个例子 希望大家给出解决方案

有个列表,有很多数据,现在分页页数达到了几十万,当我点击第一页/第二页时 很快,当我点击最后一页的时候,这个时候相应很

慢,就在这个响应过程,我点击第一页,这个时候就报错了 提示datareader 未关闭 已有打开的与此命令相关联的 DataReader,必须首先将它关闭。 之类的

代码如下

using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection))
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = conn;

rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
rd.Close();
return dt;


针对这种情况怎样处理呢
...全文
2665 53 打赏 收藏 转发到动态 举报
写回复
用AI写文章
53 条回复
切换为时间正序
请发表友善的回复…
发表回复
anzhiqiang_touzi 2012-04-16
  • 打赏
  • 举报
回复
根本就是链接未关闭。
在统一个链接上打开企图打开多个DataReader
潇洒王子 2012-04-16
  • 打赏
  • 举报
回复
我是来看大牛的
wolf_410 2012-04-16
  • 打赏
  • 举报
回复
为什么非要一次性读出来呢
fwc 2012-04-16
  • 打赏
  • 举报
回复

using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection))
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = conn;

rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
rd.Close();
return dt;


恕我愚钝,初学ASP.NET没多久,想请教各位大能:
1 从楼主的程序上看不出connection是从什么地方传过来的,应该是前面代码创建的吧(是不是前面就是创建Connection和创建command的代码,楼主省事没贴,似乎Connection没法在asp.net的页面处理线程之间共享吧)
2不管是否查询处理完,即使再点同样链接或其他链接,应该在服务器端是另外一个线程处理了吧,似乎不会导致并发冲突,最多连接池被占满,系统响应迟钝。
3 我个人感觉是不是楼主的using只包含了第一行有问题呢?如果去掉using怎么样?
  • 打赏
  • 举报
回复
[Quote=引用 46 楼 的回复:]

建议你在整个页面中只做一次数据查询操作,然后再数据存储在cache中,在每次翻页时,从cache里取数,这个速度应该很快
[/Quote]

晕死!

这样设计软件,软件公司是会倒闭的。
  • 打赏
  • 举报
回复
跟所谓“还未读完”其实没有关系。主要是因为你共享了变量(所引用的对象),这就冲突了。

应该是new一个新的对象。
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

当点击最后一页的时候 相应很慢 这个时候datareader还未读完,尚未关闭

就在这个时候 点击了第一页 就提示datareader未关闭了

如何解决这个问题


如果大数据量 最后一页读取的时候 都会很慢的吧
[/Quote]

跟所谓的并发没有关系。我怀疑你根本不知道如何多人并发测试,你的代码在多人并发是必然出错,可是你竟然说没有出错。而你只是在说在一次查询很慢时(同一个人因为等不及其结果而立刻发起了另一个查询)此时才出错。可见你只是自己做了调试,根本没有任何多用户使用的经验,也没有经过这类测试。

如果做过真正的测试,其实问题一眼就能看出来。修改过的代码就是这样的:

var cmd= CreateNewCommand(sql);
cmd.Connection = CreateNewSqlConnection();
using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
rd.Close();
return dt;
}

必须创建新的SqlCommand对象,新的(独立的)SqlConnection对象,而不能共享。

asp.net处理客户端请求是多线程并发的,因此那种以为“省得创建对象了”的代码,当然就会出现共享冲突。
心蓝168 2012-04-14
  • 打赏
  • 举报
回复
建议你在整个页面中只做一次数据查询操作,然后再数据存储在cache中,在每次翻页时,从cache里取数,这个速度应该很快
想念旧时光 2012-04-13
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 的回复:]
亲结贴了吧

我一看就知道你的底层写得太乱了
重构一下你的底层的Sql访问吧

using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection))
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = con……
[/Quote]
学习啊。
DB牛牛 2012-04-13
  • 打赏
  • 举报
回复
DATASET +存储过程分页
再针对常用查询条件加索引优化
几十万的数据应该没有什么问题
Mirror然 2012-04-13
  • 打赏
  • 举报
回复

在查询的时候 如果用户访问过大 越到后面翻页 越慢
通过单例模式修改扩充链接池 分配1-100个之间
无非在查询的时候 各分配一次 就不会出现等待状态
每次链接数据库 分配一个链接池 应该能解决

其次查询优化条件
  • 打赏
  • 举报
回复
用分页控件...
jiangshun 2012-04-13
  • 打赏
  • 举报
回复
报你那个错,本质的原因是在当前查询数据的时候适用的是上一次适用的datareader。既然是静态的,就很好理解了,都是使用的这个类的方法,而不是这个类的一个对象的方法!

1.等待时间主要是在数据库查询上面,这个不多说,优化查询语句,建合理的索引!
2.datareader对于数据量大的时候,一直保持数据库的连接状态。建议返回datatable或者dataset,这样即使查询时间久,也不会占有一个数据库连接!就asp.net而言数据库连接很宝贵啊,尽量少的减少打开连接次数,尽量减少打开时间!
3.如果一定要用datareader,个人觉得,增加数据库连接池的数量,对于datareader操作,做个对象池试试!

happytonice 2012-04-13
  • 打赏
  • 举报
回复
查询数据很影响性能
绿领巾童鞋 2012-04-13
  • 打赏
  • 举报
回复
还是没有处理好逻辑,数据库连接什么时候开,什么时候关,生命周期等等,应该都是要考虑好了...
夜色镇歌 2012-04-13
  • 打赏
  • 举报
回复
学习
IS-NULL 2012-04-13
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
首先对于数据的响应太慢。如果你数据太多 就加索引
然后 最好使用存储过程 直接返回数据集合

如果你有时间的间隔,可以采用给数据加上分割线让时间作为查询条件
[/Quote]

+1
jackingod 2012-04-13
  • 打赏
  • 举报
回复
单例 datareader 数据量大 确实会存在这个问题咯
感觉只能从用户侧 或者 改用存储分页之类的来处理比较好
alongchengtian0 2012-04-12
  • 打赏
  • 举报
回复
并发的问题,与客户端的量有关系,这个可以看看CSDN前段时间的那个讨论12306架构的,只关注高并发,大数据处理。
要是像楼主都说的这个样的话,看你的分页是存储过程还是后台拼的SQL语句,这个还要看具体的分页代码~都有关系。
siaosa 2012-04-12
  • 打赏
  • 举报
回复
SQL2012直接支持分页的SQL语句啊
分页语法:OFFSET FETCH NEXT
加载更多回复(29)

62,268

社区成员

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

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

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

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