Hi,

I looked at that pooling framework and have some comments, i hope that
i can mail them to this list.

1>
Why isn't there a closed boolean in the PoolablePreparedStatement/Connection?
If users do call the closed() method but then make a mistake and do use
the connection or the statement again, then the still can do that! (no error will apear
except when another also did get that statement again. very strange error phrone
situations can happen!!)
So i do think that there should be a closed boolean and when that one is true
no method call can be done anymore without throwing an exception.
Because there should be a boolean check the 2 delegating classes can be
discarded in this example because you in the Poolable versions you still need to
have all the methods because there should be a boolean check.

2>
Why is the Factory implementation: KeyedPoolableObjectFactory or PoolableObjectFactory
be implemented in the Normal/Outer class (PoolingConnection and BaseConnectionPool)
If find this very confusing and bad design.
Because for example PoolingConnection.makeObject(Object) what does this do?
If you look at this then you should think that it makes a PoolingConnection Object for 
the
specifiek object that is given (like Locale.getCurrencyInstance(Locale) ect ect)
This Factory implementation should really be in an other class:
PreparedStatementFactory or ConnectionFactory and if this class is absolutly only be 
used
by PoolingConnection or BaseConnectionPool they should be private innerclasses i think.

3>
the passivate methods of connection:
Why is only the autocommit and the readonly set back the the default values?
Why aren't clearWarnings(), setCatalog , setTransactionIsolation and setTypeMap called?
To get a exact copy of the original connection back?
But when calling those set methods there must be a check if it is really changed!!
  if(!conn.getCatalog().equals(this.catalog))
  {
   conn.setCatalog(this.catalog);
  }
Because if you don't do the above then the JDBC-ODBC bridge (to a acces mdb) doesn't 
work anymore
when you want to pool the prepared statements of this connection. So maybe more have 
this limitation.

The same for PreparedStatement.passivate:
Why are only the clearParameters() called?
There could be a batch() or warnings, or a left over resultset.
My close of my pooledpreparedstatement is this:

 try  {
  java.sql.ResultSet rs = _ps.getResultSet();
  if(rs != null)  {
   rs.close();
  }
 }
 catch (SQLException e) { }
 try  {
  clearBatch();
 }
 catch (SQLException sqlE) { }
 catch (UnsupportedOperationException uoe){}
 try  {
  clearParameters();
 }
 catch (Exception e) { }
 try  {
  clearWarnings();
 }
 catch (SQLException e) { }
 _bClosed = true;

4>
I am planning (or already beginning to implement) also a bit of transcaction control.
Very simple in the beginning:

User calls:
    Datasouce.startTranscation() (a transcation is started for the current thread)
    Datasource.getConnection() (a connection is created/borrowed and attached the the 
current transaction)
    Datasouce.startTranscation() (Ignored because there was already a transaction for 
the current thread, using that one)
    Datasource.getConnection() (the connection of the current transaction is 
returned!!!)
    Connection.close() (Connection is not "closed" (or returnend) yet because there is 
another one in this transaction holding on to
it)
    Connection.rollback() (At this point something is gone wrong. The 
onlyRollBackBoolean == true)
    Datasource.getConnection() (the connection of the current transaction is 
returned!!!)
    Connection.close() (Connection is not "closed" (or returnend) yet because there is 
another one in this transaction holding on to
it)
    Connection.commit() (Exception because it could only be rollbacked)
    Connection.getError() get's the error why it is gone wrong
    Connection.close() (Connection is "closed" or returnend because there is no one in 
this transaction holding on to it)


    Connection.getStatus() (Can alway's be called, returns OnlyRollBack or something 
like that)

If there is call to getConnection but there is not a current Transaction, a 
Transaction will be made.

I want this because i make my Database Objects just as Entity beans (for easy 
transaction to a EJB server at one time)
so:
    class Customer
    {
        public static Customer findCustomerByPrimaryKey(int key or PrimaryKey key)
        {
                Connection connection =  datasource.getConnection(); // Auto made a 
Transaction
                // Select the customer and makes a customer (maybe the Customer is 
Pooled in a CacheablePool see below)
                // Customer has a reference (foreign key) to another Object: Country:
                customer.setCountry(Country.findCountryByPrimaryKey(rs.getInt(x)));
        }
    }

    class Country
    {
        public static Country findCountryByPrimaryKey(int key)
        {
                // datasouce returns the same Connection, because it is in same 
transaction/thread
                // This is absolutly necessary because i would run out of connections 
when i don't get the same connection back
                // If for example only 2 connections can be made (the max value) and 
the Country also did a call to
                // another object which also called datasource.getConnection() there 
would be a deadlock!!!!
                // In the current implementation of struts/my program i give the 
current connection with the method call
                Connection connection =  datasource.getConnection();
                // Select the country
                Return country.
        }
    }

Anybody interrested or has more idee's about this?


5>
About the pooling framework:
In the GenericXXXPool classes objects are being destroyed if they are
are idle long enough. This is in a loop that is completly synchronized so when it
runs and walks through the complete list the pool is completely locked
I really would like to have an implementation that uses weak references.
So a cache object pool. Let the JVM decide when there is not enough memory anymore.
This wouldn't work for everything because you lose the abillty to call destroy (or you 
must
do this in the finalize of the wrapper around the real object)

Johan Compagner





Reply via email to