本帖最后由 wwfgu00ing 于 2012-04-10 16:51:12 编辑

解决方案 »

  1.   

    单例模式没问题,但在访问数据库的时候,其中的ado.net对象,就别用静态成员了。
      

  2.   

    我也觉得是数据库连接池的问题 大家对这些高并发 高访问量的有没有好的ORM解决方案或参考资料
      

  3.   

    自己点的多次,不能算并发吧,建议采用进度条或者遮盖的DIV,在处理数据的过程中,不允许重复操作!
    另外,提示datareader没有关闭,是否与你的方法是静态的有关系?建议尽量少使用静态调用!
      

  4.   

    当点击最后一页的时候  相应很慢 这个时候datareader还未读完,尚未关闭  就在这个时候 点击了第一页 就提示datareader未关闭了   如何解决这个问题
    如果大数据量  最后一页读取的时候  都会很慢的吧
      

  5.   

    其实这种情况并不适合用单例模式,ASP.net的数据库连接并不是单线程的。。
      

  6.   

     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;
    using 的应该是 connection
      

  7.   

    连接字符串中有个属性可以修改连接的个数
    http://www.cnblogs.com/wlb/archive/2012/04/08/2437617.html还有你确定你的那个DbDataReader实现了IDispose这个接口了吗?
     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();
    rd.dispose()//试试
                        return dt;
      

  8.   


    DbDataReader 是在这个命名空间下的System.Data.Common
      

  9.   


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

                        if (cmd.Connection.State == ConnectionState.Closed)
                            cmd.Connection = conn;
                       
                        rd = cmd.ExecuteReader();
                        DataTable dt = new DataTable();
                        dt.Load(rd);
                        rd.Close();
                        return dt;我手动插入红色的部分 冒失 就不会提示这个错误
      

  10.   

    单例模式可以保证唯一的数据库连接对象。
    但是静态成员估计会有问题吧。
    现在分页都有弊端,页数越大,效率越低下。把DataReader改成DataSet,
    DataReader 和 DataSet 最大的区别在于,DataReader 使用时始终占用 SqlConnection,在线操作数据库..任何对 SqlConnection 的操作都会引发 DataReader 的异常..因为 DataReader 每次只在内存中加载一条数据,所以占用 的内存是很小的..因为 DataReader 的特殊性和高性能.所以 DataReader 是只是 向前读的 读了第一条后就不能再去读取第一条了 dataSet 则是将数据一次性加 载在内存中.抛弃数据库连接读取完毕即放弃数据库连接因为 DataSet 将数据全 部加载在内存中.所以比较消耗内存但是确比 DataReader 要灵活
      

  11.   


    是的  数据量会很大  采用dataset的话 会很 吃内存 暂不考虑
      

  12.   


    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;你的连接最好是手动关闭
    而且连接不要是单例(静态的)的
    CommandBehavior.CloseConnection:虽然表示关闭read时关闭连接。但是C#不会即使关闭的
     try
                {
                    DataTable dt = null;
                    using (DbDataReader rd = cmd.ExecuteReader())
                    {
                        if (cmd.Connection.State == ConnectionState.Closed)
                            cmd.Connection = conn;                    rd = cmd.ExecuteReader();
                        dt = new DataTable();
                        dt.Load(rd);
                        rd.Close();
                    }
                }
                catch
                {
                    throw;
                }
                finally
                {
                    cmd.Connection.Close();
                }
                return dt;
      

  13.   

    数据查询慢,DataReader 一直占用着连接。要么不用DataReader,要么不要让用户点击其他的页码。
      

  14.   

    [color=#FF0000]    红色 
      学习中[color]
      

  15.   

    同一个连接企图打开多个DataReader
      

  16.   

    亲结贴了吧我一看就知道你的底层写得太乱了
    重构一下你的底层的Sql访问吧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; using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Data.Common;
    using System.Data; 
    using System.Web;namespace AnNet.Entity
    {
        internal abstract class DbSqlHelper : ISqlHelper
        {
            /// <summary>
            /// 事务对象
            /// </summary>
            private DbTransaction transaction;        /// <summary>
            /// 结果集
            /// </summary>
            private DbDataReader reader;
            
            /// <summary>
            /// 当前连接对象
            /// </summary>
            protected DbConnection connection;        /// <summary>
            /// 执行对象
            /// </summary>
            protected DbCommand command;        /// <summary>
            /// 获取DbDataAdapter
            /// </summary>
            protected DbDataAdapter dataAdapter;
            /// <summary>
            /// 创建连接对象
            /// </summary>
            /// <returns>创建的连接</returns>
            protected abstract DbConnection CreateConnection(string connectionString);        /// <summary>
            /// 创建DataAdapter对象
            /// </summary>
            /// <returns>创建的DataAdapter对象</returns>
            protected abstract DbDataAdapter CreateDataAdapter();        /// <summary>
            /// 构造对象实例
            /// </summary>
            public DbSqlHelper(string connectionString)
            {
                this.connection = this.CreateConnection(connectionString);
                this.command = this.connection.CreateCommand();
                this.dataAdapter = this.CreateDataAdapter();
            }        /// <summary>
            /// 获取当前的连接对象
            /// </summary>
            public DbConnection Connection
            {
                get { return connection; }
            }        /// <summary>
            /// 执行SQL语句返回受影响的行数
            /// </summary>
            /// <param name="cmdType">语句类型</param>
            /// <param name="cmdText">SQL语句</param>
            /// <returns>受影响的行数</returns>
            public int ExecuteNonQuery(CommandType cmdType, string cmdText, ParameterCollection dbParameter)
            {
                int val = 0;
                this.PrepareCommand(this.command, this.connection, this.transaction, cmdType, cmdText, dbParameter);
                val = this.command.ExecuteNonQuery();
                this.command.Parameters.Clear();
                return val;
            }
            /// <summary>
            /// 执行SQL语句返回记录集
            /// </summary>
            /// <param name="cmdType">语句类型</param>
            /// <param name="cmdText">SQL语句</param>
            /// <returns>记录集</returns>
            public DbDataReader ExecuteReader(CommandType cmdType, string cmdText, ParameterCollection dbParameter)
            {
                this.PrepareCommand(this.command, this.connection, this.transaction, cmdType, cmdText, dbParameter);
                reader = this.command.ExecuteReader();
                this.command.Parameters.Clear();
                return reader;
            }
            /// <summary>
            /// 执行SQL语句
            /// </summary>
            /// <param name="cmdType">语句类型</param>
            /// <param name="cmdText">SQL语句</param>
            /// <returns>返回数据表</returns>
            public DataTable ExecuteTable(CommandType cmdType, string cmdText, ParameterCollection dbParameter)
            {
                DataTable dt = new DataTable();
                this.PrepareCommand(this.command, this.connection, this.transaction, cmdType, cmdText, dbParameter);
                this.dataAdapter.SelectCommand = this.command;
                this.dataAdapter.Fill(dt);
                this.command.Parameters.Clear();
                return dt;
            }        /// <summary>
            /// 返回执行SQL语句第一个值
            /// </summary>
            /// <param name="cmdType">语句类型</param>
            /// <param name="cmdText">SQL语句</param>
            /// <returns>执行结果</returns>
            public object ExecuteScalar(CommandType cmdType, string cmdText, ParameterCollection dbParameter)
            {
                object val = null;
                this.PrepareCommand(this.command, this.connection, this.transaction, cmdType, cmdText, dbParameter);
                val = this.command.ExecuteScalar();
                this.command.Parameters.Clear();
                return val;
            }        private void PrepareCommand(DbCommand cmd, DbConnection conn, DbTransaction trans, CommandType cmdType, string cmdText, ParameterCollection cmdParms)
            {
                this.command.Parameters.Clear();            if (conn.State != ConnectionState.Open)
                {
                    conn.Open();
                }
                cmd.Connection = conn;
                cmd.CommandText = cmdText;
                if (trans != null)
                {
                    cmd.Transaction = trans;
                }
                cmd.CommandType = cmdType;
                if (cmdParms != null)
                {
                    foreach (DbParameter parm in cmdParms)
                    {
                        cmd.Parameters.Add(parm);
                    }
                }
            }        #region 数据库事务处理
            /// <summary>
            /// 开启事务
            /// </summary>
            public void BeginTransaction()
            {
                if (this.connection.State != ConnectionState.Open)
                {
                    this.connection.Open();
                }
                transaction = this.connection.BeginTransaction();
            }
            /// <summary>
            /// 提交事务
            /// </summary>
            public void Commit()
            {
                if (this.transaction != null)
                {
                    this.transaction.Commit();
                }
            }
            /// <summary>
            /// 回滚事务
            /// </summary>
            public void Rollback()
            {
                if (this.transaction != null)
                {
                    this.transaction.Rollback();
                }
            }
            #endregion        #region 创建数据库参数
            /// <summary>
            /// 创建参数
            /// </summary>
            /// <param name="parameterName">参数名称</param>
            /// <param name="dbType">类型</param>
            /// <param name="value">值</param>
            /// <param name="Size">大小</param>
            /// <param name="direction">Input|OutPut</param>
            public DbParameter CreateParameter(string parameterName, DbType dbType, object value, int size, ParameterDirection direction)
            {
                DbParameter ps = this.CreateParameter(parameterName, dbType, value, direction);
                ps.Size = size;
                return ps;
            }        /// <summary>
            /// 创建参数
            /// </summary>
            /// <param name="parameterName">参数名称</param>
            /// <param name="dbType">类型</param>
            /// <param name="value">值</param>
            /// <param name="Size">大小</param>
            public DbParameter CreateParameter(string parameterName, DbType dbType, object value, int size)
            {
                DbParameter ps = this.CreateParameter(parameterName, dbType, value);
                ps.Size = size;
                return ps;
            }        /// <summary>
            /// 创建参数
            /// </summary>
            /// <param name="parameterName">参数名称</param>
            /// <param name="dbType">类型</param>
            /// <param name="value">值</param>
            public abstract DbParameter CreateParameter(string parameterName, DbType dbType, object value);        /// <summary>
            /// 创建参数
            /// </summary>
            /// <param name="parameterName">参数名称</param>
            /// <param name="dbType">类型</param>
            /// <param name="value">值</param>
            /// <param name="direction">Input|OutPut</param>
            public DbParameter CreateParameter(string parameterName, DbType dbType, object value, ParameterDirection direction)
            {
                DbParameter ps = this.CreateParameter(parameterName, dbType, value);
                ps.Direction = direction;
                return ps;
            }
            #endregion        private bool alreadyDisposed = false;        /// <summary>
            /// 回收资源
            /// </summary>
            public void Dispose()
            {
                //调用带参数的Dispose方法, 释放托管和非托管资源
                Dispose(true);
                //手动调用了Dispose释放资源,那么析构函数就是不必要的了, 这里阻止GC调用析构函数        
                GC.SuppressFinalize(this);
            }        /// <summary>
            /// protected的Dispose方法, 保证不会被外部调用,传入bool值disposing以确定是否释放托管资源
            /// </summary>
            protected void Dispose(bool disposing)
            {
                //保证不重复释放  
                if (alreadyDisposed)
                    return;
                if (disposing)
                {
                    //销毁事务
                    if (transaction != null)
                    {
                        transaction.Dispose();
                        transaction = null;
                    }
                    //关闭游标
                    if (reader != null && reader.IsClosed == false)
                    {
                        reader.Close();
                        reader.Dispose();
                        reader = null;
                    }
                    //关闭连接
                    if (connection != null && connection.State == ConnectionState.Open)
                    {
                        connection.Close();
                        connection.Dispose();
                        connection = null;
                    }
                }
                alreadyDisposed = true;
            }
        }
    }
      

  17.   

    SQL2012直接支持分页的SQL语句啊
    分页语法:OFFSET FETCH NEXT
      

  18.   

    并发的问题,与客户端的量有关系,这个可以看看CSDN前段时间的那个讨论12306架构的,只关注高并发,大数据处理。
    要是像楼主都说的这个样的话,看你的分页是存储过程还是后台拼的SQL语句,这个还要看具体的分页代码~都有关系。   
      

  19.   

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

  20.   

    DATASET +存储过程分页
    再针对常用查询条件加索引优化
    几十万的数据应该没有什么问题
      

  21.   

    单例 datareader 数据量大 确实会存在这个问题咯 
      感觉只能从用户侧 或者 改用存储分页之类的来处理比较好
      

  22.   

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

  23.   


    跟所谓的并发没有关系。我怀疑你根本不知道如何多人并发测试,你的代码在多人并发是必然出错,可是你竟然说没有出错。而你只是在说在一次查询很慢时(同一个人因为等不及其结果而立刻发起了另一个查询)此时才出错。可见你只是自己做了调试,根本没有任何多用户使用的经验,也没有经过这类测试。如果做过真正的测试,其实问题一眼就能看出来。修改过的代码就是这样的:
     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处理客户端请求是多线程并发的,因此那种以为“省得创建对象了”的代码,当然就会出现共享冲突。
      

  24.   

    跟所谓“还未读完”其实没有关系。主要是因为你共享了变量(所引用的对象),这就冲突了。应该是new一个新的对象。
      

  25.   

    根本就是链接未关闭。
    在统一个链接上打开企图打开多个DataReader
      

  26.   


    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怎么样?