Tomcat和WebLogic在使用连接池处理CLOB字段的诡异问题

上篇文章说到在Oracle PL/SQL中如何处理CLOB字段,现在来说说这几天碰到的一个诡异问题

为了符合业务部门的要求,需要将一些数据存储到CLOB字段中,当然,在日常的生产系统上当然是使用ConnectionPool来连接数据库的了,代码段如下:

     public Connection getJdbcConnection(){
      Connection conn = null;
      try {
   conn = getJdbcTemplate().getDataSource().getConnection();
    } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   }
      return  conn;
     }

处理代码段如下:

......    
oracle.sql.CLOB clobtt = null;
    if(rs.next()){
        clobtt = (oracle.sql.CLOB)rs.getClob(1);
        Writer wr = clobtt.getCharacterOutputStream();
        char[] b = obj.getValue1().toCharArray();
......

运行结果:
ClassCastException

奇怪了,难道是我的Driver用错了(这时我使用的是Tomcat DataSource),查看了common/lib下的driver,classes12.jar!没错呀。。等一下,好像不对,怎么才1.04MB,这个是Oracle9i R1的Driver,当然是不包括oracle.sql.CLOB对象的,更换(classes12.jar是1.14MB的)

写了一段测试,代码如下(连接方式采用DriverManager方式测试):

 public Connection getConnectionDB(){
  Connection conn = null;
  try {
   Class.forName("XXXXXXXXXXXXXXXXX");
   conn = DriverManager.getConnection("XXXXXXX","XXXXX","XXXXX");
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (SQLException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
  }
  return conn;
 }

哈哈,结果是成功的,然后更换到生产机上运行。。。晕,使用DataSource还是ClassCastException,查找了一翻。。还是一样的问题,难道是tomcat不支持CLOB方式?更换至weblogic,同样问题。。。

我有点晕了,通过如下方式进行Debug捕捉,看看到底对象中是什么:

Object o = rs.getClob(1);
结果是oracle.sql.CLOB,晕了。。那怎么会在使用DataSource的情况下就ClassCastException呢?使用DriverManager却不会发生?查看一下WEB-INF\lib下的包,没有任何问题

考虑再三,首先先要解决问题,由于项目开发中使用tomcat(开发人员的机器太烂,没办法在开发环境也用weblogic),QA和现场均使用weblogic DataSource,而且客户现场不可以在配制文件中出现密码明文、考虑到performance,所以使用DriverManager是不现实的

实现代码如下:
......
   //获取J2EE服务器类型 1-tomcat 0-weblogic
   String r = ((Gparam)getParamByCode("1050")).getValue1();
   
   Connection conn = null;
   if("1".equals(r)){//tomcat
    conn = jdbcManager.getConnectionDB();
   }else if("0".equals(r)){//weblogic
    conn = jdbcManager.getJdbcConnection();
   }

   conn.setAutoCommit(false);
   ResultSet rs = null;
   
   String sql=getLparamSQL(obj,editMode);
   PreparedStatement stmt = conn.prepareStatement(sql);
 
   stmt.executeUpdate();
   sql = "SELECT VALUE1,VALUE2 FROM LPARAM WHERE KEY = "+obj.getKey()+" AND USERID="+obj.getUserid()+" FOR UPDATE";
   stmt = conn.prepareStatement(sql);
   rs= stmt.executeQuery();

   if("1".equals(r)){//tomcat
    oracle.sql.CLOB clobtt = null;
    if(rs.next()){
        clobtt = (oracle.sql.CLOB)rs.getClob(1);
        Writer wr = clobtt.getCharacterOutputStream();
        char[] b = obj.getValue1().toCharArray();
        wr.write(b);
        wr.flush();
        wr.close();
       
        clobtt = (oracle.sql.CLOB)rs.getClob(2); 
        wr = clobtt.getCharacterOutputStream();
        b = obj.getValue2().toCharArray();
        wr.write(b);
        wr.flush();
        wr.close();
     }
   }else if("0".equals(r)){//weblogic
    weblogic.jdbc.vendor.oracle.OracleThinClob clobtt = null;
    if(rs.next()){
        clobtt = (weblogic.jdbc.vendor.oracle.OracleThinClob)rs.getClob(1);
        Writer wr = clobtt.getCharacterOutputStream();
        char[] b = obj.getValue1().toCharArray();
        wr.write(b);
        wr.flush();
        wr.close();
       
        clobtt = (weblogic.jdbc.vendor.oracle.OracleThinClob)rs.getClob(2); 
        wr = clobtt.getCharacterOutputStream();
        b = obj.getValue2().toCharArray();
        wr.write(b);
        wr.flush();
        wr.close();
     }
   }

   rs.close();
   stmt.close();
   conn.commit();
   conn.close();
......

在weblogic环境下使用weblogic.jdbc.vendor.oracle.OracleThinClob专用方式来进行处理,在tomcat环境下使用driverManager,然后通过系统配置文件进行开关式配置,用来解决2个矛盾的问题

通过以上处理来看,解决事情还是要多动脑精,不能死钻。。。
关于JDBC Driver的这个疑问还有待深入研究。。。等待下文

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/111631/viewspace-605995/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/111631/viewspace-605995/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值