痛苦的windows20003+oracle10g+tomcat连接池迁移之旅

原创 2005年06月01日 13:56:00

我的痛苦的windows20003+oracle10g+tomcat连接池迁移之旅

项目开发中完成,在开发环境中是在windowsxp和用自己的连接池开发的,oracle数据库的版本是8。17。

重大问题1:windows2003的问题,微软的正版软件我看也不见的好到那里去。那个windows20003server版本比盗版的还低,装上后还需要激活,激活的工序可是麻烦的要了命。他好像使用了限制一台计算机使用,如果你再这个计算机上安装了这套软件,并且通过电话激活或internet激活方式激活了该操作系统,那么这套操作系统只能再这个计算机上使用了,其他的计算机上不能安装了,安装完了,无法激活!

后来他们销售的通过和微软的多次打电话才解决了这个问题。保证了在那台服务器上能激活。

重大问题2:网上下载的oracle10g无法安装。安装中间报错误:unable to create item in start menu and desktop........,多么郁闷的问题。多次网上查询都没有着相关的问题。找遍了google也没有找到。难道就没有人遇到过。让他们集成的人多次重新安装系统还是不行。到底是那里的问题呢?后来想到了需要用别的软件试验一下,于是拷了一个金山词霸进行安装,奇怪的是他显示的界面都是乱码,最后也报告无法在开始菜单和桌面上创建快捷方式。到底是那里的问题了,开始以为是权限的问题,修改administrator的权限多次,都没解决,最后才知道了是windows本地语言设置的问题。原来是他没有设置好本地的语言。中文的版本,本地语言设置为英文就出现了这么多无法解释的错误。真是要了人的命。不过现在想想,也是,他按照英文找中文的开始菜单,当然找不到了。

重大问题3:

开始搬迁程序了。导入了oracle数据库,从oracle8上备份到oracle10g上到没有什么问题。主要是我们的dba比较厉害。然后开始配置打包程序war文件。放到tomcat上,在tomcat上配置了连接池。修改了程序中获得连接的地方。放上去,发现不行。报错:network adapter........好像是网络没有找到。哦,发现是网线掉了。后来报错,驱动不对,到oracle安装的计算机上找到了他下面的lib/jdbc/的驱动替换掉以前的oracle8的程序。重新部署,报告说找不到驱动。对了把驱动程序到拷贝到了tomcat/common/lib/,然后启动,连接池成功配置。成功登陆了系统。ok?no.最后一个可怕的问题出现了。再读取oracle10g中clob字段的时候报错误。ClassCastException,查看包错误的程序就在:oracle.sql.CLOB clog=(Oracle.sql.CLOB)rs.getClob("clob_text");开始我们认为这是一个多么难解决的问题。我估计可能是那里的转换类型错误了。没想到这个问题害的我整整折腾了2天。

棘手的痛苦的问题4

这个问题确实不那么简单。我开始怀疑是oracle10g驱动的问题。我加载了全部的oracle10g的驱动,尽管网上说如果是在jdk1。4以上的版本,只需要加载其中的一个ojdbc14。jar包。但是事情害是不行。错误仍然,我开始在google上找这个问题。在sun的开坛上的这个帖子给了我很大的帮助:oracle.sql.CLOB+ClassCastException 这个问题网上很多。

http://forum.java.sun.com/thread.jspa?threadID=349880&start=15

这个帖子有各种各样的解决方法。我挨个试验了。

看到了他们使用oracle提供的创建临时clob的方法。

oracle.sql.CLOB newClob = oracle.sql.CLOB.createTemporary(conn, false, oracle.sql.CLOB.DURATION_CALL);
依然不行,还是同样的错误发生,我急了,让他打印看看取道的到底是什么对象,缺是java.sql.Clob这个我早知道,打印了了白打,我想把他转换到oracle的clob就是不行。使用创建临时的clob是他的那个连接不能使用。该死的,这个从tomcat5。0中获得的连接池怎么不行呢。后来看到帖子上有人用con的类型转换,转换成oraclejdbcconnnection。于是我也试验了。还不行。后来在其他西班牙的网站上看到了他使用了一个jboss下的包转换wapper,转换成jboss的连接,说是成功了。我开始试验,代码拷贝过来,发现没有jboss的那个common包,于是网上down下来。加载进去,编译通过。放到服务器上。这次不包错误了,但是执行到那里,你等半个小时都过去去。一个字,烂。

马上抛开了这个方法。jboss的东西抛弃掉了。后来在oracle的官方网站上看到熬了oracle公司提供的oracle10g中如何使用jdbc的例子。试验了。还是不行,真不知道他们这些东西是怎么提供处来的。不过在这理看到一个oracle驱动加载的新的方法

import java.sql.Connection;
import java.sql.DriverManager;
import oracle.jdbc.OracleDriver;
import java.util.Properties;
..........  

// Load the database details into the variables.
String url      = "jdbc:oracle:thin:@localhost:1521:orcl";
String user     = "scott";
String password = "tiger";

// Create the properties object that holds all database details
Properties props = new Properties();
props.put("user", user );
props.put("password", password);
props.put("SetBigStringTryClob", "true");

// Load the Oracle JDBC driver class.
DriverManager.registerDriver(new OracleDriver());    

// Get the database connection
Connection conn = DriverManager.getConnection( this.url, this.props );

我怀疑props.put("SetBigStringTryClob", "true");东西很有用,于是在tomcat的连接池配置的server.xml中也添加了这个属性参数。配置后,在读取clob的时候,我按照oracle网站提供的直接使用了getString这个方法,庆幸的是ok了,可以读取出来了。

但是更新方法不行,按照他们给提供的。

这是他们给提供的方法:

ClobManipulationIn10g



oracle.otnsamples.jdbc;

java.sql.Connection;
java.sql.DriverManager;
java.sql.Statement;
java.sql.PreparedStatement;
java.sql.ResultSet;
java.sql.SQLException;

oracle.jdbc.OracleDriver;

java.io.IOException;
java.io.BufferedReader;
java.io.FileNotFoundException;
java.io.FileReader;

java.util.Properties;


ClobManipulationIn10g {


Connection conn = ;


String url = ;
String user = ;
String password = ;

Properties props = Properties();


String fileName = ;


ClobManipulationIn10g(String fileName) {
.fileName = fileName;
}


main(String[] args) SQLException {

ClobManipulationIn10g clobManipulationIn10g =
ClobManipulationIn10g(args[]);

DriverManager.registerDriver( OracleDriver());

String dbUrl = ;
clobManipulationIn10g.url = dbUrl;

clobManipulationIn10g.user = ;

clobManipulationIn10g.password = ;

clobManipulationIn10g.props.put(, clobManipulationIn10g.user );
clobManipulationIn10g.props.put(, clobManipulationIn10g.password);
clobManipulationIn10g.props.put(, );

clobManipulationIn10g.checkTables();

clobManipulationIn10g.insertClob();
clobManipulationIn10g.selectClob();

}


insertClob() SQLException {

PreparedStatement pstmt = ;

{
((conn==)||conn.isClosed()){
conn = DriverManager.getConnection( .url, .props );
}

String sql = ;

String str = .readFile();

pstmt = conn.prepareStatement(sql);

pstmt.setString(,str);

pstmt.executeUpdate();

} (SQLException sqlex) {
System.out.println( +
+ sqlex.toString());
} (Exception ex) {
System.out.println( +
+ ex.toString());
} {
(pstmt!=) pstmt.close();
(conn!=) conn.close();
}
}


selectClob() SQLException {

PreparedStatement pstmt = ;

ResultSet rset = ;
{
((conn==)||conn.isClosed()){
conn = DriverManager.getConnection( .url, .props );
}

String sqlCall = ;
pstmt= conn.prepareStatement(sqlCall);

rset = pstmt.executeQuery();

String clobVal = ;

(rset.next()) {
clobVal = rset.getString();
System.out.println(+clobVal.length());
}

} (SQLException sqlex) {
System.out.println( +
+ sqlex.toString());
} (Exception ex) {
System.out.println( +
+ ex.toString());
} {
(rset !=) rset.close();
(pstmt!=) pstmt.close();
(conn!=) conn.close();
}
}


checkTables() {

Statement stmt = ;
ResultSet rset = ;
{

((conn==)||conn.isClosed()){
conn = DriverManager.getConnection( .url, .props );
}

stmt = conn.createStatement();

rset = stmt.executeQuery(+
);

(!rset.next()) {
stmt.executeUpdate();
}

} (SQLException sqlEx) {
System.out.println(
+sqlEx.toString());
} {
{
( rset != ) rset.close();
( stmt != ) stmt.close();
(conn!=) conn.close();
} (SQLException ex) {
System.out.println(
+ex.toString());
}
}
}


String readFile()
FileNotFoundException, IOException{

BufferedReader br = BufferedReader( FileReader(fileName));
String nextLine = ;
StringBuffer sb = StringBuffer();
((nextLine = br.readLine()) != ) {

sb.append(nextLine);
}
String clobData = sb.toString();

clobData;
}
}

最后只好再想其他的方法。发现有人研究tomcat的连接池,他自己写了tomcat的连接的转换类,来获得他的实际的连接实现类:

tempclob= CLOB.createTemporary(DbcpNativeJdbcExtractor.getNativeConnection(conn), true, CLOB.DURATION_SESSION);

public class DbcpNativeJdbcExtractor{

public static Connection getNativeConnection(Connection con) throws SQLException {

if (con instanceof DelegatingConnection) {
Connection nativeCon = ((DelegatingConnection) con).getInnermostDelegate();

// For some reason, the innermost delegate can be null: not for a
// Statement's Connection but for the Connection handle returned by the pool.
// We'll fall back to the MetaData's Connection in this case, which is
// a native unwrapped Connection with Commons DBCP 1.1.

return (nativeCon != null ? nativeCon : con.getMetaData().getConnection());
}
return con;
}
}

我也试验了,编译每问题。运行到数据库执行更新clob类型的时候,就没反映了,死掉了。该死的,

这种获得tomcat实际连接的转行都不行。我服了。。。。。。。。

继续想办法。发现在开始的那个帖子上。

http://forum.java.sun.com/thread.jspa?threadID=349880&start=15&tstart=0 

上给提供了一种可以用流来处理clob的类型。但我开始试验没有通过,现在又开始重新研究,

别人都说行。我这里怎么就不行呢。哦。我突然发现程序中又一个变量的bug。

tmd,可能是他的原因。我修改了程序。重新运行。ok。终于搞定了。我的代码也乱成一团了。

但最后实现clob的操作的方法总结了2条:

1。如果读取clob类型的字段,你设置上"SetBigStringTryClob", "true"这个环境变量,应该没有问题的。

2、如果你要更新clob。如果是低于oracle10g的版本。用一般的方法都可以。但是10g中就用流来处理吧。

其他的转换成oracle.sql.CLOB的方法我是每找到,主要是老报错误。这和使用tomcat5的连接池有关系。

如果使用自己的连接池,问题应该不大。

参考代码:1。可以直接使用getString方法来获得clob的数据

/**
   *从ResultSet种来获得某列的CLOB的String值
   * @param colName
   * @return
   */
  public String getClobStr(ResultSet rs, String columnName) throws SQLException {
    //
//    StringBuffer sb = new StringBuffer();
//    Writer clobWriter = ( (oracle.sql.CLOB) rs.getClob(columnName)).
//        getCharacterOutputStream();
//
//    try {
//      clobWriter.write(sb.toString());
//      clobWriter.close();
//    }
//    catch (IOException ex1) {
//      ex1.printStackTrace();
//    }
//
//    return sb.toString();
//    Object value =((OracleResultSet) rs).getCLOB(columnName);
    return rs.getString(columnName);
//        Object value =rs.getClob(columnName);
//    System.out.println("getObject(columnName).getClass()======="+value.getClass());
//    CLOB clob = (CLOB) value;
//    java.io.Reader instream = clob.getCharacterStream();
//    // create temporary buffer for read
//    char[] buffer = new char[10000];
//
//    String l = "";
//    try {
//      long length = instream.read(buffer);
//
//      // length of characters read
//
//      l = null;
//      l = String.copyValueOf(buffer);
//      instream.close();
//    }
//    catch (IOException ex) {
//      ex.printStackTrace();
//    }
//
//    return l.trim();

  }

/**
   *   要更新clob类型的数据
   * @param idName 你的表的主键的名称
   * @param id 你的主键的值如:100000
   * @param tableName 你要操作的表名
   * @param column 你的要更新的字符串的列名的集合
   * @param value 你要更新的CLOB的值字符串集合
   */
  public void updateClob(String idName, long id, String tableName,
                         String[] column, String[] value) {

    //
    String cloStr = "";
    if (column != null)
      for (int i = 0; i < column.length; i++) {
        cloStr += column[i] + "=?,";
      }
    cloStr = cloStr.substring(0, cloStr.length() - 1);
    String parStr = getParaStr(value.length);
    String sql = "";
    sql = "update  " + tableName + " set " + cloStr + " where " + idName + "=" +
        id;
    System.out.println("sql = " + sql);
    List list = new ArrayList();
    PreparedStatement opstmt = null;
    try {
      opstmt = con.prepareStatement(sql);
      for (int i = 0; i < column.length; i++) {
        StringReader fis = new java.io.StringReader(value[i]);
        opstmt.setCharacterStream( (i + 1), fis, (int) value[i].length());
        System.out.println("ps.setAsciiStream((i+1)==" + (i + 1));
        list.add(fis);
      }
      opstmt.executeUpdate();
      con.commit();
      for (int i = 0; i < list.size(); i++) {
        try {
          ( (StringReader) list.get(i)).close();
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }
      }

    }
    catch (SQLException sqlex) {
      sqlex.printStackTrace();
    }
    finally {
      try {
        con.setAutoCommit(true);
        if (opstmt != null) {
          opstmt.close();
        }
      }
      catch (SQLException sqlex) {
        sqlex.printStackTrace();
      }
    }
  }

//多次修改,多次的修改记录的代码片断。没有成功的。留个纪念:

=============垃圾代码===================

    oracle.sql.CLOB tempclob = oracle.sql.CLOB.createTemporary(((WrappedConnection) con).getUnderlyingConnection() , false, oracle.sql.CLOB.DURATION_CALL);
//        oracle.sql.CLOB  tempclob = CLOB.createTemporary(con, true, CLOB.DURATION_SESSION);
//          tempclob.open(CLOB.MODE_READWRITE); //mode d'ouverture
//         oracle.sql.CLOB tempclob= CLOB.createTemporary(DbcpNativeJdbcExtractor.getNativeConnection(con), true, CLOB.DURATION_SESSION);
        /*  oracle.sql.CLOB tempclob = oracle.sql.CLOB.createTemporary(con, false, oracle.sql.CLOB.DURATION_CALL);
          Writer tempClobWriter = tempclob.getCharacterOutputStream();
          try {
            tempClobWriter.write(value[i].toCharArray());
            tempClobWriter.flush();
            tempClobWriter.close();
            tempclob.close();
          }
          catch (SQLException ex) {
            ex.printStackTrace();
          }
          catch (IOException ex) {
            ex.printStackTrace();
          }

          ps.setClob((i+1),tempclob);
         */
        ps.setString((i=1),value[i]);

//          oracle.sql.CLOB newClob = oracle.sql.CLOB.createTemporary(con, false, oracle.sql.CLOB.DURATION_CALL);
//          newClob.putString(1,value[i]);
//          opstmt.setClob( (i + 1), newClob);
            StringReader  fis =new java.io.StringReader (value[i]);
            ps.setCharacterStream((i+1), fis, (int) value[i].length());
            System.out.println("ps.setAsciiStream((i+1)=="+(i+1));

=============垃圾代码===================

这次经历。我让我长了不少知识,认识到许多版本之间的区别。也感觉到了windows2003的糟粕,oracle10g驱动的烂。tomcat连接池的局限性等等。

希望能给别人带来点小小的帮助。让我们引以为戒,深入研究。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Tomcat7.0与Oracle10数据库连接池配置

数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库连接池正式针对这个问题提出...

tomcat创建oracle 10g的JDBC连接池

在一个web程序中,往往要对数据库进行多次的操作,每次操作都加载驱动和创建新连接,代码量很大,我们可以通过在web容器中(例如tomcat等)配置数据库连接池,方便我们在程序中的调用。       ...
  • zy4668
  • zy4668
  • 2012年05月22日 11:37
  • 811

tomcat6.0+oracle10g数据源连接测试

1、拷贝驱动包 在oracle目录下的\product\10.2.0\db_1\jdbc\lib 拷贝ojdbc14.jar文件到 tomcat目录下的lib目录中;客车网 客车 2、tom...

Oracle10g RMAN Windows 2003 Server R2 x64备份迁移到Linux x64

记录源端windows上oracle的dbid SQL> select dbid from v$database; DBID ---------- 66428446 使用RMAN备份...

Windows下Oracle10g32位迁移到11g64位

客户 window平台,oracle从10.2.0.1.升级到10.2.0.5。

jbpm4.3安装(jbpm4.3+tomcat6+oracle10g)

A、准备工作: 1、安装JDK1.6或者更高的版本,并且配置好环境变量。 2、安装STS-Spring Tool Suite,MyEclipse也可以。 3、下载jbpm4.3 ,下载地址: ...

心得之:linux下安装jdk tomcat oracle10g

最近一直在研究linux环境的操作,其实之前一直没有实际需求要用到linux,因项目需要,突然接受,显得很局促和苦闷,因我对linux的操作太不熟悉了,基本命令使用起来都很苦逼。现在突然需要搭建lin...

RED HAT 5.5 Linux下安装配置JDK+TOMCAT+Oracle10g

RED HAT 5.5 Linux下安装配置JDK+TOMCAT+Oracle10g    1. linux配置java环境变量 1.1 解压安装jdk     在shell终端下进入jdk-...

jbpm4.3 + spring3.0 +oracle10g+hibernate3+tomcat6 集成笔记

版本信息: jbpm4.3 spring 3.0 oracle 10g hibernate3.6.10-final tomcat 6.0.26 为了方便说明,本文中jbpm4.3的安装根目录记录为 J...

Oracle10g在Windows2008上安装

有一个系统环境是这样,数据库是Oracle 10.2.0.4,操作系统是windows2003。现在采购了新的服务器,但该服务器不支持windows2003,只能安装windows2008。 如何在...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:痛苦的windows20003+oracle10g+tomcat连接池迁移之旅
举报原因:
原因补充:

(最多只允许输入30个字)