Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 935|回复: 0

SqlServer数据库连接池溢出问题解决

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-4 16:51:15 | 显示全部楼层 |阅读模式

    今天解决了一个大Bug——数据库连接池溢出问题,问题在于,DAL层的DbHelper类中的ExecuteReader()方法创建了大量未及时关闭的SqlConnection,致使网站在小规模负载压力下崩溃。

    当初的DbHelper类是根据网上给出的参考设计(51aspx.net)的,没想到这个例子也有漏洞,源代码如下:

            public static SqlDataReader ExecuteReader(String sqlText)
            {
                SqlCommand cmd = new SqlCommand();
                SqlConnection conn = new SqlConnection(ConnectionString);
                try
                {
                    conn.Open();
                    cmd.Connection = conn;
                    cmd.CommandText = sqlText;
                    SqlDataReader reader = cmd.ExecuteReader();
                    return reader;
                }
                catch (Exception e)
                {
                    conn.Close();
                    throw e;
                    return null;
                }
            }

    这样做的好处是:BLL与DAL只依靠sqlstring耦合,BLL中数据库操作的语句更少。但是,以上代码并没有及时关闭创建的数据库连接

    修改如下:

            public static SqlDataReader ExecuteReader(String sqlText, SqlConnection conn)
            {
                SqlCommand cmd = new SqlCommand();
                try
                {
                    conn.Open();
                    cmd.Connection = conn;
                    cmd.CommandText = sqlText;
                    SqlDataReader reader = cmd.ExecuteReader();
                    return reader;
                }
                catch (Exception e)
                {
                    
                    conn.Close();
                    throw e;
                   // return null;
                }
            }

    BLL层使用代码(语句已高亮):

           /// <summary>
            /// 获得未回答的问题
            /// </summary>
            /// <param name="tagId">0表示获取所有分类</param>
            /// <param name="pageNum"></param>
            /// <param name="totalPageNum"></param>
            /// <param name="queryType">0-default.aspx,1-list</param>
            /// <returns></returns>
            public List<Question> GetUnansweredQuestion(int tagId,int pageNum,ref int totalPageNum,int queryType)
            {
                List<Question> list = new List<Question>();
                String sql;
                if (queryType == 0)
                    sql = "SELECT TOP 10 Question.* FROM [Question] WHERE replies = 0";
                else if(tagId>0)
                    sql = String.Format("SELECT TOP {0} * FROM (SELECT Question.*,ROW_NUMBER() OVER (ORDER BY created DESC) AS RowNumber FROM [Question],[QuestionTagAssociation] WHERE Question.replies = 0 AND Question.qid = QuestionTagAssociation.qid AND QuestionTagAssociation.tid = {2}) A WHERE RowNumber > {0} * ({1}-1)", pageSize, pageNum, tagId);
                else
                    sql = String.Format("SELECT TOP {0} * FROM (SELECT Question.*,ROW_NUMBER() OVER (ORDER BY created DESC) AS RowNumber FROM [Question] WHERE Question.replies = 0) A WHERE RowNumber > {0} * ({1}-1)", pageSize, pageNum);
    
                SqlConnection conn = DbHelper.getConnection(); SqlDataReader reader = DbHelper.ExecuteReader(sql, conn);
                fillQuestionList(list, reader);
    
                reader.Close(); conn.Close(); if (queryType != 0)
                {
                    if(tagId>0)
                        sql = String.Format("SELECT count(*) FROM [Question],[QuestionTagAssociation] WHERE Question.replies = 0 AND Question.tid = QuestionTagAssociation.tid AND QuestionTagAssociation.tid = {0}", tagId);
                    else
                        sql = "SELECT count(*) FROM [Question] WHERE Question.replies = 0";
                    totalPageNum = (int)Math.Floor((double)DbHelper.getSingleInt(sql)/pageSize);
                    
                }
        
                return list;
            }

    修改后,系统在小规模负载压力下正常运行。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-22 21:00 , Processed in 0.058889 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表