User: oleg    
  Date: 00/10/03 10:32:13

  Modified:    src/main/org/jboss/minerva/jdbc ConnectionInPool.java
                        PSCacheKey.java PreparedStatementInPool.java
  Log:
  PreparedStatement pool bugfixes:
  1) Two wrapper PreparedStatements could use the same "real" one at the same time,
  so that ps2.executeQuery() closed the ResultSet obtained by ps1.executeQuery().
  Now PreparedStatements are removed from the pool on con.prepareStatement()
  and are returned to the pool on ps.close().
  2) A PreparedStatement with wrong ResultSetType and ResultSetConcurrency
  could be fetched from the pool.
  Now ResultSetType and ResultSetConcurrency are included to the pool key.
  
  Revision  Changes    Path
  1.4       +30 -10    jboss/src/main/org/jboss/minerva/jdbc/ConnectionInPool.java
  
  Index: ConnectionInPool.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/minerva/jdbc/ConnectionInPool.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ConnectionInPool.java     2000/08/31 17:28:47     1.3
  +++ ConnectionInPool.java     2000/10/03 17:32:12     1.4
  @@ -10,6 +10,7 @@
   import java.sql.Connection;
   import java.sql.DatabaseMetaData;
   import java.sql.PreparedStatement;
  +import java.sql.ResultSet;
   import java.sql.SQLException;
   import java.sql.SQLWarning;
   import java.sql.Statement;
  @@ -28,7 +29,7 @@
    * outstanding statements are closed, and the connection is rolled back.  This
    * class is also used by statements, etc. to update the last used time for the
    * connection.
  - * @version $Revision: 1.3 $
  + * @version $Revision: 1.4 $
    * @author Aaron Mulder ([EMAIL PROTECTED])
    */
   public class ConnectionInPool implements PooledObject, ConnectionWrapper {
  @@ -113,6 +114,21 @@
        */
       public void statementClosed(Statement st) {
           statements.remove(st);
  +        if (st instanceof PreparedStatementInPool) {
  +            // Now return the "real" statement to the pool
  +            PreparedStatementInPool ps = (PreparedStatementInPool) st;
  +            int rsType = ResultSet.TYPE_FORWARD_ONLY;
  +            int rsConcur = ResultSet.CONCUR_READ_ONLY;
  +            // We may have JDBC 1.0 driver
  +            try {
  +                rsType = ps.getResultSetType();
  +                rsConcur = ps.getResultSetConcurrency();
  +            } catch (Throwable th) {
  +            }
  +            PreparedStatementInPool.preparedStatementCache.put(
  +                    new PSCacheKey(con, ps.getSql(), rsType, rsConcur),
  +                    ps.getUnderlyingPreparedStatement());
  +        }
       }
   
       /**
  @@ -164,14 +180,16 @@
       public PreparedStatement prepareStatement(String sql) throws SQLException {
           if(con == null) throw new SQLException(CLOSED);
           try {
  -            PreparedStatement ps = 
(PreparedStatement)PreparedStatementInPool.preparedStatementCache.get(
  +            // Seek in the pool and remove if found: the same "real" 
PreparedStatement
  +            // cannot be used by two wrappers since ps.executeQuery() closes all
  +            // ResultSets of the PreparedStatement that may be in use through other 
wrappers.
  +            // The "real" statement will be returned to the pool on 
PreparedStatementInPool.close().
  +            PreparedStatement ps = 
(PreparedStatement)PreparedStatementInPool.preparedStatementCache.remove(
                                           new PSCacheKey(con, sql));
               if(ps == null) {
                   ps = con.prepareStatement(sql);
  -                PreparedStatementInPool.preparedStatementCache.put(
  -                                        new PSCacheKey(con, sql), ps);
               }
  -            PreparedStatementInPool wrapper = new PreparedStatementInPool(ps, this);
  +            PreparedStatementInPool wrapper = new PreparedStatementInPool(ps, this, 
sql);
               statements.add(wrapper);
               return wrapper;
           } catch(SQLException e) {
  @@ -361,14 +379,16 @@
       public PreparedStatement prepareStatement(String sql, int resultSetType, int 
resultSetConcurrency) throws SQLException {
           if(con == null) throw new SQLException(CLOSED);
           try {
  -            PreparedStatement ps = 
(PreparedStatement)PreparedStatementInPool.preparedStatementCache.get(
  -                                        new PSCacheKey(con, sql));
  +            // Seek in the pool and remove if found: the same "real" 
PreparedStatement
  +            // cannot be used by two wrappers since ps.executeQuery() closes all
  +            // ResultSets of the PreparedStatement that may be in use through other 
wrappers.
  +            // The "real" statement will be returned to the pool on 
PreparedStatementInPool.close().
  +            PreparedStatement ps = 
(PreparedStatement)PreparedStatementInPool.preparedStatementCache.remove(
  +                                        new PSCacheKey(con, sql, resultSetType, 
resultSetConcurrency));
               if(ps == null) {
                   ps = con.prepareStatement(sql, resultSetType, resultSetConcurrency);
  -                PreparedStatementInPool.preparedStatementCache.put(
  -                                        new PSCacheKey(con, sql), ps);
               }
  -            PreparedStatementInPool wrapper = new PreparedStatementInPool(ps, this);
  +            PreparedStatementInPool wrapper = new PreparedStatementInPool(ps, this, 
sql);
               statements.add(wrapper);
               return wrapper;
           } catch(SQLException e) {
  
  
  
  1.2       +15 -2     jboss/src/main/org/jboss/minerva/jdbc/PSCacheKey.java
  
  Index: PSCacheKey.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/minerva/jdbc/PSCacheKey.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- PSCacheKey.java   2000/08/30 16:17:05     1.1
  +++ PSCacheKey.java   2000/10/03 17:32:12     1.2
  @@ -1,22 +1,35 @@
   package org.jboss.minerva.jdbc;
   
   import java.sql.Connection;
  +import java.sql.ResultSet;
   
   public class PSCacheKey {
       public Connection con;
       public String sql;
  +    public int rsType;
  +    public int rsConcur;
   
       public PSCacheKey(Connection con, String sql) {
           this.con = con;
           this.sql = sql;
  +        this.rsType = ResultSet.TYPE_FORWARD_ONLY;
  +        this.rsConcur = ResultSet.CONCUR_READ_ONLY;
       }
   
  +    public PSCacheKey(Connection con, String sql, int rsType, int rsConcur) {
  +        this.con = con;
  +        this.sql = sql;
  +        this.rsType = rsType;
  +        this.rsConcur = rsConcur;
  +    }
  +
       public boolean equals(Object o) {
           PSCacheKey key = (PSCacheKey)o;
  -        return key.con.equals(con) && key.sql.equals(sql);
  +        return key.con.equals(con) && key.sql.equals(sql) &&
  +               key.rsType == rsType && key.rsConcur == rsConcur;
       }
   
       public int hashCode() {
  -        return con.hashCode() ^ sql.hashCode();
  +        return con.hashCode() ^ sql.hashCode() ^ rsType ^ rsConcur;
       }
   }
  
  
  
  1.2       +11 -1     
jboss/src/main/org/jboss/minerva/jdbc/PreparedStatementInPool.java
  
  Index: PreparedStatementInPool.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/minerva/jdbc/PreparedStatementInPool.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- PreparedStatementInPool.java      2000/08/30 16:18:41     1.1
  +++ PreparedStatementInPool.java      2000/10/03 17:32:12     1.2
  @@ -31,15 +31,17 @@
       private final static String CLOSED = "PreparedStatement has been closed!";
       private PreparedStatement impl;
       private ConnectionWrapper con;
  +    private String sql;
   
       /**
        * Creates a new statement from a source statement and wrapper connection.
        */
  -    public PreparedStatementInPool(PreparedStatement source, ConnectionWrapper 
owner) {
  +    public PreparedStatementInPool(PreparedStatement source, ConnectionWrapper 
owner, String sql) {
           super(source, owner);
           if(source == null || owner == null) throw new NullPointerException();
           impl = source;
           con = owner;
  +        this.sql = sql;
       }
   
       /**
  @@ -52,6 +54,13 @@
           return impl;
       }
   
  +    /**
  +     * Returns the SQL Statement string.
  +     */
  +    public String getSql() {
  +        return sql;
  +    }
  +
       // ---- Implementation of java.sql.Statement ----
   
       public ResultSet executeQuery() throws SQLException {
  @@ -412,5 +421,6 @@
           con.statementClosed(this);
           con = null;
           impl = null;
  +        sql = null;
       }
   }
  
  
  

Reply via email to