贝网博客

我的分类
流水记事
源码下载
Asp.net
其它
数据库
Javascript
.Net技术
我的相册
友情链接
博客园
CSDN博客
Start0
最新回复
fasdfasdf
[:..
lz这个东西好厉害,我..
哈哈,好照片
不错,以前一直用黄色..
终于找到支持ff的修正..
终于找到支持ff的修正..
新鲜性
看看,试试,好不好使。
好东西一起学习[:img0..
分类 =》.Net技术
SqlDataReader读取的数据量太大,导致Close超时的问题及解决
发表于:2012-12-15 11:14:54
更新于:2012-12-15 11:15:55

今天在进行数据同步时,通过SqlDataReader读取全部的100万数据,传给SqlBulkCopy复制到其它数据库,在复制前需要检查源表和目标表结构是否一致,如果不一致就不同步,直接返回,代码大致如下:

using (SqlDataReader reader = SqlHelper.ExecuteReader(m_sourceCon, "select * from tb"))
{
    if(源表结构与目标表结构不一致){
        MessageBox.Show("结构不一致");
        return;
    }
    // 开始SqlBulkCopy的代码
}

在上面的代码里,tb表的数据量为100万条,每次走到MessageBox后都会超时,即使调整ExecuteReader的Timeout为更长时间也不行,始终是30秒左右超时,通过修改代码反复调查,发现是走到using的结束时超时,于是在if代码框里增加reader.Close(),果然,就是在Close的时候导致的超时

在同事的帮助下,发现在MSDN上对Close方法有个说明:
Close 方法填写输出参数的值、返回值和 RecordsAffected,从而增加了关闭用于处理大型或复杂查询的 SqlDataReader 所用的时间。 如果返回值和查询影响的记录的数量不重要,则可以在调用 Close 方法前调用关联的 SqlCommand 对象的 Cancel 方法,从而减少关闭 SqlDataReader 所需的时间。

原来如此,把ExecuteReader代码修改一下,把SqlDataReader的Command对象返回,并通过调用Command.Cancel()方法来避免这个问题,修改后的代码:

SqlCommand command;
using (SqlDataReader reader = SqlHelper.ExecuteReader(m_sourceCon, "select * from tb", out command))
{
    if(源表结构与目标表结构不一致){
        command.Cancel();
        MessageBox.Show("结构不一致");
        return;
    }
    // 开始SqlBulkCopy的代码
}

至此,问题解决,比较郁闷的就是,SqlHelper.ExecuteReader方法需要多加一个out参数

发表评论
名称(*):
邮箱:
正文:

©2008 Beinet.cn 版权所有