日期:2014-05-20  浏览次数:20704 次

某OA系统修改记录
我们集团多年前上了一套OA系统,jsp   +   javabean   +   servlet,没有使用任何框架,model1。
数据库:SqlServer   2000
web服务器:Resin   2.1.6
开发者是合肥某家专业OA公司,应该是为我们定制的。具体情况我当时没有入职,不清楚。
从我第一天使用它就感觉很慢。近日发现经常死机,一天需要多次重启服务。2G内存,4CPU的服务器,经常cpu100%,全被sqlserver占用,db连动数动辄上千。


观察了一天,得出结论:要想彻底解决,只有辛苦一番了。
此次修改不涉及业务逻辑部分。
动手修改之后怒火却逐渐上升,好在凭借几十年的修身养性平息下来了,不过一天下来却得感冒,不知道是否跟这个有关。
笔录一些东西,感慨一番。或供大家批判、或引以为鉴。当年写程序的那个小伙子,如果你能看到,不知道有没有什么感慨呢?

   
(1)死机最主要原因出在数据库连接的管理上。

        数据库连接类(DBConnectionManager.java)。
        数据库操作类(DBQuery.java),在构造函数中取得DBConnectionManager的一个单例。
        该类特点是在方法executeQuery、executeUpdate之中,每次都从连接池中申请一个连接。
        DBQuery通过java   Bean使用,而在绝大部分jsp页面都包含:
<jsp:useBean   id= "dbquery "   class= "front.DBQuery "   scope= "page "/>
        也就是说打开一个页面,就产生一个Connection,观察到的sqlserver连接峰值3200+   ,即使是ORACLE,也很夸张。
        至于为什么这样,参考(2)。

        另外,还有一个函数返回值是ResultSet,但是在函数最后调用了freeConnection(),经常抛出“连接已关闭”错误也就不奇怪了。


(2)JSP页面中直接调用dbquery执行SQL查询。除少数正常关闭外,大部分ResultSet只管打开,不管关闭。正所谓:只管杀来不管埋!有魄力!
另外还有一部分是这样写的,我算他关闭了一半-_-!:
ResultSet   myrs2=dbquery.executeQuery( "xxxxxx ");
if(myrs2.next()){
myrs2.close();
}

有个地方还加了一个判断:
i   =   0;
while(rs.next()){
i   ++;
}
if(i   >   0)
rs.close();
这种……。


另附一个超强文件,文件名:whcqd_cc.jsp   (22k),只要一编辑,eclipse立即停止响应,cup   100%,无法解析文档结构图。只好结束进程,转到ultraedit中修改。
这个文件一部分代码如下:
  zuzhirs1   =   dbquery.executeQuery( "…… ");
//查找一级组织
        while(zuzhrs1.next()){
        zuzhirs2   =   dbquery.executeQuery( "…… ");
        //查找二级组织
        while(zuzhirs2.next()){
          ……
          //查找七级组织
          zuzhirs7   =   dbquery.executeQuery( "…… ");
        while(zuzhirs7.next()){
  ……
        }
        zuzhirs7.close();     //太震撼了,居然关闭了第七个rs
        }
       
        }
       
    7个zuzhirs中,关闭1/7。

(3)sql语句的优化,很少使用关联查询,最常见的是,需要用到时,随时打开一个游标查询(请考虑第一条、第二条),例如:
rs1   =   dbquery.executeQuery( "取用户信息 ");
while(rs1.next()){
String   yhh   =   rs1.getString( "yhh ");   //用户号
String   yhmc;
rstmp   =   dbquery.executeQuery( "select   名称   from   xxx   where   yhh   =   ' "   +   yhh   +   " ' ";
if(rstmp.next()){
yhmc   =   rstmp.getString( "名称 ");
}
……
//下一个类似的循环
}

某个大小45k的文件,名称:W_userdef_sqmodi.jsp,改完后我直接昏倒,清醒后不忘作了一个统计:
count(ResultSet)   ==   34
count(while)   ==   16


(4)超强的分页算法。
rs=dbquery.executeQuery( "select   xxx,   xxx   from   tablexxx     order   by   mail_date   desc ");
 
  i   =   (intPage-1)   *   intPageSize;