这个例子比较清晰,WEB多线程使我的代码执行变成如下步骤,只有最后一个Statement被释放,其它没有成功释放。stmt1 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt1.executeQuery(strSQL);stmt2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt2.executeQuery(strSQL);stmt3 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt3.executeQuery(strSQL);stmt1.close();
stmt2.close();
stmt3.close();

解决方案 »

  1.   

    从Statement上得到的rs会给程序员使用,但只有在释放rs对象时,才能Statement对象,因为Statement必须后于rs对象释放,所以Statement会被长时间占有(大于rs对象使用时间),如果SQL Server的Connection只能创建一个Statement的话,Statement将长时间占用Connection,对Connection的连接池功效就无法充分发挥,因为由于rs的长时间使用,会引用Connection的数量大增。
      

  2.   

    stmt1 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    rs = stmt1.executeQuery(strSQL);stmt2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    rs = stmt2.executeQuery(strSQL);stmt3 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    rs = stmt3.executeQuery(strSQL);stmt1.close();
    stmt2.close();
    stmt3.close();
      

  3.   

    HaulZhu(倪郝)说得很有道理,或者你选择用连接池来管理!
      

  4.   

    你可以只用一个stmt,比如:
    stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);rs = stmt.executeQuery(strSQL);
    while(re.next){
        do...
    }rs = stmt.executeQuery(strSQL);
    while(re.next){
        do...
    }rs = stmt.executeQuery(strSQL);
    while(re.next){
        do...
    }stmt.close();
      

  5.   

    我也Up一下我也Up两下!!!
    ^@^
      

  6.   

    Leemaasn,你这家伙不怀好意:P
    是不是?
    哈哈
      

  7.   

    你用完了就把它释放呀,而且没必要创建这么多Statement,用一个就可以了。stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);rs = stmt.executeQuery(strSQL);
    rs.close();rs = stmt.executeQuery(strSQL);
    rs.close();rs = stmt.executeQuery(strSQL);
    rs.close();stmt.close();
      

  8.   

    用连接池
    或者用RowSet来代替ResultSet,RowSet可以在关闭数据库连接的情况下仍然持有数据库查询所得的数据
      

  9.   

    是啊!
    这个问题的根本是我提供了一个方法
    RunSQLReturnRS(strSQL)
    这个方法返回了ResultSet,而连接池必须在ResultSet使用完毕后才能得到空闭的Connection,才能将Connection给其它请求使用。rongrongGsr:不知RowSet和ResultSet具体如何操作?
    另外,在一个Connection创建多个Statement有什么说法,听说Oracle可以,而SQL2K不行,请高手赐教。
      

  10.   

    建议一个Statement下只挂一个ResultSet。如要挂多个,建议关闭先。
      

  11.   

    /**
     * Releases this <code>Statement</code> object's database 
     * and JDBC resources immediately instead of waiting for
     * this to happen when it is automatically closed.
         * It is generally good practice to release resources as soon as
     * you are finished with them to avoid tying up database
     * resources.
         * <P><B>Note:</B> A <code>Statement</code> object is automatically closed when it is
         * garbage collected. When a <code>Statement</code> object is closed, its current
         * <code>ResultSet</code> object, if one exists, is also closed.  
         *
         * @exception SQLException if a database access error occurs
         */
        void close() throws SQLException;
    看jdk1.3的源码,statement.close()被关闭时,它所创建的ResultSet会被自动关闭。
    而Connection.close()时,其下的statement并没有自动被释放,需要手动释放。
      

  12.   

    rs = stmt.executeQuery(strSQL1);
    rs.close();rs = stmt.executeQuery(strSQL2);
    rs.close();rs = stmt.executeQuery(strSQL3);
    rs.close();这样执行有时候会失败。stmt要重新创建。
      

  13.   

    SQL SERVER 2000,创建Connection不需要花多少时间,但创建Statement,PreparedStatement却需要花时间。在java使用SQL SERVER 2000,不能像其它数据库使用通用的连接池,因为,它会在一定的时间自动关闭与SQL SEVER2000的连接。我前做过一测试:我试着将Statement创建后,不关闭,3天后,statement这个连接对象依然保持着!所以,你需要做一个Statement连接池!Statement可以带有一个数量的ResultSet对象,具体个数我还没有测试!一般而言,一个ResultSet对应一个Statement!当resultset关闭,则将statement放到池中,以备使用!还有呢为了提高服务器启动后的响影速度,可以写一个listener,在web启动后,预备20个statement以备随时启用!补充一下:sql server 的Connection对象,在运行statement或PreparedStatement后会保留一个活动的statement,以备下次使用!