一个奇怪的bug

 
        前段时间我们的WEBLOGIC应用总是运行一段时间(有时一天,有时几天)后系统CPU达到100%,重启WEBLOGIC又好了,数据库是ORACLE9.2.很是郁闷,查了一下日志发现是新部署的一个应用客户端请求后有时不能返回,估计是这个原因引起的CPU达到100%。在我的TOMCAT上测试没有问题,难道是WEBLOGIC不如TOMCAT。由于这台WEBLOGIC上部署了其它许多的应用,以为可能是一些应用冲突的问题,后来把其它不相关的应用都删除了,问题还是一样。因为时间原因一下子找不到问题的根源,还好应用是一个查询分析系统,不是7*24的,所以也只能是每次慢了后重新启动WEBLOGIC。
 
        这两天抽了点时间来解决这个问题,在公司的测试机上也发现同样的问题,于是心里比较有底,毕竟可以重现的问题一般都能解决。
        生产系统是四年前安装的,是WEBLOGIC8.1.2,公司的测试机是WEBLOGIC8.1.4,我的开发机(笔记本)也是WEBLOGIC8.1.4,都产生了同样的问题,但是我的开发机TOMCAT5.0测试时一切正常。
首先想估计是WEBLOGIC的问题。由于我的台式机是最WEBLOGIC8.1.6,所以在台式机是重新发布了一下应用,测试后发现没有问题。看来真的是WEBLOGIC的BUG,但是总是不死心,可能是做数据库多了,总想找到问题的根源。
因为我的新模块比较简单(这个项目比较老,没有用数据层的框架,就是一个jdbc的SQL,然后返回查询结果List,最后用JSP加STRTUS显示),如果WEBLOGIC这样的应用都有BUG那真的比较恐怖。
细下心来一步一步的调试。
        首先把JSP表现层去了,发现问题依然存在,于是肯定不是JSP表现层的问题。
        把断点放在STRUTS ACTION中,发现SQL执行正常,不过SQL执行的时间感觉比在PL/SQL Developer中执行的时间短,但从JDBC resultset生成list时不返回结果,出现CPU忙,于是断定问题肯定在这里。现在基本上找到了问题点,应该是JDBC驱动的问题。于是找了一下WEBLOGIC8.1.4和TOMCAT5.0的ORACLE jdbc驱动文件对比一下看看,它们的大小及MANIFEST.MF文件内容如下:
 
--WEBLOGIC8.1.4 ojdbc.jar(大小:1,353,229 字节)
Manifest-Version: 1.0
Implementation-Version: "Oracle JDBC Driver version - 10.1.0.2.0"
Specification-Title:    "Oracle JDBC driver classes for use with JDK1.
 4"
Specification-Version:  "Oracle JDBC Driver version - 10.1.0.2.0"
Implementation-Title:   "ojdbc14.jar"
Created-By: 1.2.2 (Sun Microsystems Inc.)
Implementation-Time:    "Mon May 10 13:00:11 2004"
Implementation-Vendor:  "Oracle Corporation"
Specification-Vendor:   "Oracle Corporation" .
 
--TOMCAT5.0 ojdbc.jar(大小:1,536,979 字节)
Manifest-Version: 1.0
Specification-Title:    Oracle JDBC driver classes for use with JDK14
Sealed: true
Created-By: 1.4.2_08 (Sun Microsystems Inc.)
Implementation-Title:   ojdbc14.jar
Specification-Vendor:   Oracle Corporation
Specification-Version:  Oracle JDBC Driver version - "10.2.0.1.0"
Implementation-Version: Oracle JDBC Driver version - "10.2.0.1.0"
Implementation-Vendor:  Oracle Corporation
Implementation-Time:    Wed Jun 22 18:55:48 2005
 
 
 
从上面信息可以看到
WEBLOGIC8.1.4 ojdbc.jar是10.1.0.2.0,
TOMCAT5.0 ojdbc.jar是10.2.0.1.0。
 

        我把TOMCAT的ojdbc.jar覆盖到WEBLOGIC8.1.4中,重新测试发现问题解决,所以可以下结论是jdbc驱动的问题,和应用服务器weblogic没有关系,那为什么weblogic8.1.4以前的版本有问题,而weblogic8.1.6没问题呢,这个其实是BEA weblogic在每次发布新的版本时都会更新一些第三方产品的驱动,weblogic8.1.6的oracle jdbc驱动版本是10.2.0.2.0,所以没有问题。
 
        本该问题结束,但是还是不死心,是什么原因会导至老版本的oracle jdbc驱动有BUG。于是仔细调试了一下SQL并检查结果集。以下是出问题的SQL,这个SQL是由两部份结果集UNION ALL起来的。比较复杂,不用细看。
 
select a.dq_bh,
       c.dq_jc_cn,
       d.bm_mc,
       to_char(b.gb_bh) gb_bh,
       b.gb_mc,
       cast('公变' as varchar(4)) byq_lb,
       sum(nvl(gdl, 0) + nvl(tz_gdl, 0)) gdl,
       sum(nvl(sdl, 0) + nvl(tz_sdl, 0)) sdl,
       sum(nvl(gdl, 0) + nvl(tz_gdl, 0) - nvl(sdl, 0) - nvl(tz_sdl, 0)) xs_dl,
       decode(nvl(sum(nvl(gdl, 0) + nvl(tz_gdl, 0)), 0),
              0,
              null,
              sum(nvl(gdl, 0) + nvl(tz_gdl, 0) - nvl(sdl, 0) -
                  nvl(tz_sdl, 0)) / sum(nvl(gdl, 0) + nvl(tz_gdl, 0))) * 100 xsl,
       avg(xs_zb) xs_zb,
       sum(sj_hs) sj_hs
  from v_xs_jg_tjgb a, v_zl_gybyq b, zl_dq c, v_zl_sybm d
 where a.gb_bh = b.gb_bh
   and a.dq_bh = b.dq_bh
   and a.dq_bh = c.dq_bh
   and a.dq_bh = d.dq_bh
   and a.bm_bh = d.bm_bh
   and a.dffs_ny >= ?
   and a.dffs_ny <= ?
   and a.xl_bh = ?
   and a.dq_bh = ?
   and a.pc_lx = '1'
 group by a.dq_bh, b.gb_bh, b.gb_mc, a.dq_bh, c.dq_jc_cn, d.bm_mc
union all
select /*+ use_nl(a,c)*/
 c.dq_bh,
 c.dq_jc_cn,
 c.bm_mc,
 c.hbs_bh,
 c.kh_mc,
 '专变',
 sum(a.sy_dl) gdl,
 sum(a.sy_dl) sdl,
 0,
 0,
 null,
 1
  from v_jg_bdl a, zl_yhjbqk c
 where a.dq_bh = ?
   and a.xl_bh = ?
   and a.hbs_bh = c.hbs_bh
   and a.dq_bh = c.dq_bh
   and a.dffs_ny >= ?
   and a.dffs_ny <= ?
   and a.dl_sx = '有功'
   and a.jl_sd = '全'
   and a.gb_bh is null
 group by c.dq_bh, c.hbs_bh, c.kh_mc, c.dq_jc_cn, c.bm_mc;
 
        从表面上看以为是cast('公变' as varchar(4)) byq_lb这个语法导至的问题,但是改变后问题依旧存在。经过多次测试后发现是UNION ALL后面一个SQL 引起的问题。但是把UNION ALL中任意一个SQL去除问题就没有了。所以可以说明是SQL UNION ALL引起的问题。但是有时又没有问题,多次测试后发现是某一些数据不会产生问题,某些数据会产生问题。再检查产生问题的具体的数据,发现是下面sum(a.sy_dl) sdl这一列的数据引起的问题。然后仔细检查了并修改sy_dl的数据,发现只要把一行为空的记录sy_dl字段值由空值改为其它值就没有问题。
 
        看来产生问题的原因真是复杂,首先是WEBLOGIC8.1.4的oracle jdbc驱动有问题,然后是特定的复杂的SQL加上特定的数据在这个驱动下产生问题,当然也可能是这个驱动(10.1.0.2.0)和oracle数据库版本(9.2.0.7)有冲突,由于没有ojdbc的源码,所以不好往下找问题了。

你可能感兴趣的:(ORACLE,JAVA,weblogic,jdbc,oracle,tomcat,sql,测试)