struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Johan Compagner" <jcompag...@j-com.nl>
Subject Database pooling comments (org.apache.struts.sql)
Date Thu, 08 Mar 2001 14:24:14 GMT
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






Mime
View raw message