|
From: <me...@us...> - 2002-10-04 04:38:03
|
Update of /cvsroot/cayenne/cayenne/src/cayenne/java/org/objectstyle/cayenne/conn
In directory usw-pr-cvs1:/tmp/cvs-serv28149/src/cayenne/java/org/objectstyle/cayenne/conn
Modified Files:
PoolManager.java
Log Message:
synchronized connection pool access
Index: PoolManager.java
===================================================================
RCS file: /cvsroot/cayenne/cayenne/src/cayenne/java/org/objectstyle/cayenne/conn/PoolManager.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- PoolManager.java 4 Oct 2002 04:23:51 -0000 1.2
+++ PoolManager.java 4 Oct 2002 04:37:58 -0000 1.3
@@ -60,6 +60,8 @@
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.ListIterator;
import javax.sql.ConnectionEvent;
@@ -79,329 +81,321 @@
* @author Andrei Adamchik
*/
public class PoolManager implements DataSource, ConnectionEventListener {
- static Logger logObj = Logger.getLogger(PoolManager.class.getName());
+ static Logger logObj = Logger.getLogger(PoolManager.class.getName());
- protected ConnectionPoolDataSource poolDataSource;
- protected int minConnections;
- protected int maxConnections;
- protected String dataSourceUrl;
- protected String jdbcDriver;
- protected String password;
- protected String userName;
+ protected ConnectionPoolDataSource poolDataSource;
+ protected int minConnections;
+ protected int maxConnections;
+ protected String dataSourceUrl;
+ protected String jdbcDriver;
+ protected String password;
+ protected String userName;
- private ArrayList unusedPool;
- private ArrayList usedPool;
+ protected List unusedPool;
+ protected List usedPool;
- /** Creates new PoolManager using org.objectstyle.cayenne.conn.PoolDataSource
- * for an underlying ConnectionPoolDataSource. */
- public PoolManager(
- String jdbcDriver,
- String dataSourceUrl,
- int minCons,
- int maxCons,
- String userName,
- String password)
- throws SQLException {
+ /** Creates new PoolManager using org.objectstyle.cayenne.conn.PoolDataSource
+ * for an underlying ConnectionPoolDataSource. */
+ public PoolManager(
+ String jdbcDriver,
+ String dataSourceUrl,
+ int minCons,
+ int maxCons,
+ String userName,
+ String password)
+ throws SQLException {
- this.jdbcDriver = jdbcDriver;
- this.dataSourceUrl = dataSourceUrl;
- PoolDataSource poolDS = new PoolDataSource(jdbcDriver, dataSourceUrl);
- init(poolDS, minCons, maxCons, userName, password);
- }
+ this.jdbcDriver = jdbcDriver;
+ this.dataSourceUrl = dataSourceUrl;
+ PoolDataSource poolDS = new PoolDataSource(jdbcDriver, dataSourceUrl);
+ init(poolDS, minCons, maxCons, userName, password);
+ }
- /** Creates new PoolManager with the specified policy for
- * connection pooling and a ConnectionPoolDataSource object.
- *
- * @param poolDataSource data source for pooled connections
- * @param minCons Non-negative integer that specifies a minimum number of open connections
- * to keep in the pool at all times
- * @param maxCons Non-negative integer that specifies maximum number of simultaneuosly open connections
- *
- * @throws SQLException if pool manager can not be created.
- */
- public PoolManager(
- ConnectionPoolDataSource poolDataSource,
- int minCons,
- int maxCons,
- String userName,
- String password)
- throws SQLException {
- init(poolDataSource, minCons, maxCons, userName, password);
- }
+ /** Creates new PoolManager with the specified policy for
+ * connection pooling and a ConnectionPoolDataSource object.
+ *
+ * @param poolDataSource data source for pooled connections
+ * @param minCons Non-negative integer that specifies a minimum number of open connections
+ * to keep in the pool at all times
+ * @param maxCons Non-negative integer that specifies maximum number of simultaneuosly open connections
+ *
+ * @throws SQLException if pool manager can not be created.
+ */
+ public PoolManager(
+ ConnectionPoolDataSource poolDataSource,
+ int minCons,
+ int maxCons,
+ String userName,
+ String password)
+ throws SQLException {
+ init(poolDataSource, minCons, maxCons, userName, password);
+ }
- /** Initializes pool. Normally called from constructor. */
- private void init(
- ConnectionPoolDataSource poolDataSource,
- int minCons,
- int maxCons,
- String userName,
- String password)
- throws SQLException {
+ /** Initializes pool. Normally called from constructor. */
+ protected void init(
+ ConnectionPoolDataSource poolDataSource,
+ int minCons,
+ int maxCons,
+ String userName,
+ String password)
+ throws SQLException {
- // do sanity checks...
- if (maxConnections < 0) {
- throw new SQLException(
- "Maximum number of connections can not be negative ("
- + maxCons
- + ").");
- }
+ // do sanity checks...
+ if (maxConnections < 0) {
+ throw new SQLException(
+ "Maximum number of connections can not be negative (" + maxCons + ").");
+ }
- if (minConnections < 0) {
- throw new SQLException(
- "Minimum number of connections can not be negative ("
- + minCons
- + ").");
- }
+ if (minConnections < 0) {
+ throw new SQLException(
+ "Minimum number of connections can not be negative (" + minCons + ").");
+ }
- if (minConnections > maxConnections) {
- throw new SQLException("Minimum number of connections can not be bigger then maximum.");
- }
+ if (minConnections > maxConnections) {
+ throw new SQLException("Minimum number of connections can not be bigger then maximum.");
+ }
- // init properties
- this.userName = userName;
- this.password = password;
- this.minConnections = minCons;
- this.maxConnections = maxCons;
- this.poolDataSource = poolDataSource;
+ // init properties
+ this.userName = userName;
+ this.password = password;
+ this.minConnections = minCons;
+ this.maxConnections = maxCons;
+ this.poolDataSource = poolDataSource;
- // init pool
- usedPool = new ArrayList(maxConnections);
- unusedPool = new ArrayList(maxConnections);
- growPool(minConnections, userName, password);
- }
+ // init pool
+ usedPool = Collections.synchronizedList(new ArrayList(maxConnections));
+ unusedPool = Collections.synchronizedList(new ArrayList(maxConnections));
+ growPool(minConnections, userName, password);
+ }
- /** Creates and returns new PooledConnection object. */
- private PooledConnection newPooledConnection(
- String userName,
- String password)
- throws SQLException {
- if (userName != null)
- return poolDataSource.getPooledConnection(userName, password);
- else
- return poolDataSource.getPooledConnection();
- }
+ /** Creates and returns new PooledConnection object. */
+ protected PooledConnection newPooledConnection(String userName, String password)
+ throws SQLException {
+ return (userName != null)
+ ? poolDataSource.getPooledConnection(userName, password)
+ : poolDataSource.getPooledConnection();
+ }
- /** Closes all existing connections, removes them from the pool. */
- public void dispose() throws SQLException {
- // clean connections from the pool
- ListIterator unusedIterator = unusedPool.listIterator();
- while (unusedIterator.hasNext()) {
- PooledConnection con = (PooledConnection) unusedIterator.next();
- // close connection
- con.close();
- // remove connection from the list
- unusedIterator.remove();
- }
+ /** Closes all existing connections, removes them from the pool. */
+ public synchronized void dispose() throws SQLException {
- // clean used connections
- ListIterator usedIterator = usedPool.listIterator();
- while (usedIterator.hasNext()) {
- PooledConnection con = (PooledConnection) usedIterator.next();
- // stop listening for connection events
- con.removeConnectionEventListener(this);
- // close connection
- con.close();
- // remove connection from the list
- usedIterator.remove();
- }
- }
+ // clean connections from the pool
+ ListIterator unusedIterator = unusedPool.listIterator();
+ while (unusedIterator.hasNext()) {
+ PooledConnection con = (PooledConnection) unusedIterator.next();
+ // close connection
+ con.close();
+ // remove connection from the list
+ unusedIterator.remove();
+ }
- /** Increase connection pool by the specified number of connections..
- * Throw SQLException if no more connections are allowed, or if
- * an error happens when creating a new connection.
- */
- private void growPool(int addConnections, String userName, String password)
- throws SQLException {
- if (unusedPool.size() + usedPool.size() + addConnections
- > maxConnections) {
- StringBuffer msg = new StringBuffer();
- msg
- .append("An attempt to open more connections ")
- .append("than pool is allowed to handle.")
- .append(
- "\n\tCurrent size: "
- + (unusedPool.size() + usedPool.size()))
- .append("\n\tTrying to open: " + addConnections)
- .append("\n\tMax allowed: " + maxConnections);
- throw new SQLException(msg.toString());
- }
+ // clean used connections
+ ListIterator usedIterator = usedPool.listIterator();
+ while (usedIterator.hasNext()) {
+ PooledConnection con = (PooledConnection) usedIterator.next();
+ // stop listening for connection events
+ con.removeConnectionEventListener(this);
+ // close connection
+ con.close();
+ // remove connection from the list
+ usedIterator.remove();
+ }
+ }
- for (int i = 0; i < addConnections; i++) {
- PooledConnection newConnection =
- newPooledConnection(userName, password);
- newConnection.addConnectionEventListener(this);
- unusedPool.add(newConnection);
- }
- }
+ /** Increase connection pool by the specified number of connections..
+ * Throw SQLException if no more connections are allowed, or if
+ * an error happens when creating a new connection.
+ */
+ protected synchronized void growPool(
+ int addConnections,
+ String userName,
+ String password)
+ throws SQLException {
- private void shrinkPool(int closeConnections) throws SQLException {
- int close =
- unusedPool.size() < closeConnections
- ? unusedPool.size()
- : closeConnections;
- int lastInd = unusedPool.size() - close;
+ if (unusedPool.size() + usedPool.size() + addConnections > maxConnections) {
+ StringBuffer msg = new StringBuffer();
+ msg
+ .append("An attempt to open more connections ")
+ .append("than pool is allowed to handle.")
+ .append("\n\tCurrent size: " + (unusedPool.size() + usedPool.size()))
+ .append("\n\tTrying to open: " + addConnections)
+ .append("\n\tMax allowed: " + maxConnections);
+ throw new SQLException(msg.toString());
+ }
- for (int i = unusedPool.size() - 1; i >= lastInd; i--) {
- PooledConnection con = (PooledConnection) unusedPool.remove(i);
- con.close();
- }
- }
+ for (int i = 0; i < addConnections; i++) {
+ PooledConnection newConnection = newPooledConnection(userName, password);
+ newConnection.addConnectionEventListener(this);
+ unusedPool.add(newConnection);
+ }
+ }
- /**
- * Returns maximum number of connections this pool can keep.
- * This parameter when configured allows to limit the number of simultaneously
- * open connections.
- */
- public int getMaxConnections() {
- return maxConnections;
- }
+ protected synchronized void shrinkPool(int closeConnections) throws SQLException {
+ int close =
+ unusedPool.size() < closeConnections ? unusedPool.size() : closeConnections;
+ int lastInd = unusedPool.size() - close;
- public void setMaxConnections(int maxConnections) {
- this.maxConnections = maxConnections;
- }
+ for (int i = unusedPool.size() - 1; i >= lastInd; i--) {
+ PooledConnection con = (PooledConnection) unusedPool.remove(i);
+ con.close();
+ }
+ }
- /** Returns the absolute minimum number of connections allowed
- * in this pool at any moment in time. */
- public int getMinConnections() {
- return minConnections;
- }
+ /**
+ * Returns maximum number of connections this pool can keep.
+ * This parameter when configured allows to limit the number of simultaneously
+ * open connections.
+ */
+ public int getMaxConnections() {
+ return maxConnections;
+ }
- public void setMinConnections(int minConnections) {
- this.minConnections = minConnections;
- }
+ public void setMaxConnections(int maxConnections) {
+ this.maxConnections = maxConnections;
+ }
- /** Returns a database URL used to initialize this pool.
- * Will return null if the pool was initialized with ConnectionPoolDataSource. */
- public String getDataSourceUrl() {
- return dataSourceUrl;
- }
+ /** Returns the absolute minimum number of connections allowed
+ * in this pool at any moment in time. */
+ public int getMinConnections() {
+ return minConnections;
+ }
- /** Returns a name of a JDBC driver used to initialize this pool.
- * Will return null if the pool was initialized with ConnectionPoolDataSource. */
- public String getJdbcDriver() {
- return jdbcDriver;
- }
+ public void setMinConnections(int minConnections) {
+ this.minConnections = minConnections;
+ }
- /** Returns a data source password used to initialize this pool. */
- public String getPassword() {
- return password;
- }
+ /** Returns a database URL used to initialize this pool.
+ * Will return null if the pool was initialized with ConnectionPoolDataSource. */
+ public String getDataSourceUrl() {
+ return dataSourceUrl;
+ }
- /** Returns a data source user name used to initialize this pool. */
- public String getUserName() {
- return userName;
- }
+ /** Returns a name of a JDBC driver used to initialize this pool.
+ * Will return null if the pool was initialized with ConnectionPoolDataSource. */
+ public String getJdbcDriver() {
+ return jdbcDriver;
+ }
- /**
- * Returns the number of connections obtained via this DataSource
- * that are currently in use by the DataSource clients.
- */
- public int getCurrentlyInUse() {
- return usedPool.size();
- }
+ /** Returns a data source password used to initialize this pool. */
+ public String getPassword() {
+ return password;
+ }
- /**
- * Returns the number of connections maintained in the
- * pool that are currently not used by any clients and are
- * available immediately via <code>getConnection</code> method.
- */
- public int getCurrentlyUnused() {
- return unusedPool.size();
- }
+ /** Returns a data source user name used to initialize this pool. */
+ public String getUserName() {
+ return userName;
+ }
- /**
- * Returns connection from the pool using internal values of user name
- * and password. Eqivalent to calling:
- *
- * <p><code>ds.getConnection(ds.getUserName(), ds.getPassword())</code></p>
- */
- public synchronized Connection getConnection() throws SQLException {
- return getConnection(userName, password);
- }
+ /**
+ * Returns the number of connections obtained via this DataSource
+ * that are currently in use by the DataSource clients.
+ */
+ public int getCurrentlyInUse() {
+ return usedPool.size();
+ }
- /** Returns connection from the pool. */
- public Connection getConnection(String userName, String password)
- throws SQLException {
+ /**
+ * Returns the number of connections maintained in the
+ * pool that are currently not used by any clients and are
+ * available immediately via <code>getConnection</code> method.
+ */
+ public int getCurrentlyUnused() {
+ return unusedPool.size();
+ }
- // security check
- int totalCon = usedPool.size() + unusedPool.size();
- if (totalCon > maxConnections) {
- shrinkPool(totalCon - maxConnections);
- }
+ /**
+ * Returns connection from the pool using internal values of user name
+ * and password. Eqivalent to calling:
+ *
+ * <p><code>ds.getConnection(ds.getUserName(), ds.getPassword())</code></p>
+ */
+ public synchronized Connection getConnection() throws SQLException {
+ return getConnection(userName, password);
+ }
- // increase pool if needed
- // if further increase is not possible
- // (say we exceed the maximum number of connections)
- // this will throw an SQL exception...
- if (unusedPool.size() == 0) {
- growPool(1, userName, password);
- }
+ /** Returns connection from the pool. */
+ public Connection getConnection(String userName, String password)
+ throws SQLException {
- int lastObjectInd = unusedPool.size() - 1;
- PooledConnection pooledConn =
- (PooledConnection) unusedPool.remove(lastObjectInd);
- usedPool.add(pooledConn);
- return pooledConn.getConnection();
- }
+ // security check
+ int totalCon = usedPool.size() + unusedPool.size();
+ if (totalCon > maxConnections) {
+ shrinkPool(totalCon - maxConnections);
+ }
- public int getLoginTimeout() throws java.sql.SQLException {
- return poolDataSource.getLoginTimeout();
- }
+ // increase pool if needed
+ // if further increase is not possible
+ // (say we exceed the maximum number of connections)
+ // this will throw an SQL exception...
+ if (unusedPool.size() == 0) {
+ growPool(1, userName, password);
+ }
- public void setLoginTimeout(int seconds) throws java.sql.SQLException {
- poolDataSource.setLoginTimeout(seconds);
- }
+ int lastObjectInd = unusedPool.size() - 1;
+ PooledConnection pooledConn = (PooledConnection) unusedPool.remove(lastObjectInd);
+ usedPool.add(pooledConn);
+ return pooledConn.getConnection();
+ }
- public PrintWriter getLogWriter() throws java.sql.SQLException {
- return poolDataSource.getLogWriter();
- }
+ public int getLoginTimeout() throws java.sql.SQLException {
+ return poolDataSource.getLoginTimeout();
+ }
- public void setLogWriter(PrintWriter out) throws java.sql.SQLException {
- poolDataSource.setLogWriter(out);
- }
+ public void setLoginTimeout(int seconds) throws java.sql.SQLException {
+ poolDataSource.setLoginTimeout(seconds);
+ }
- /** Returns closed connection to the pool. */
- public synchronized void connectionClosed(ConnectionEvent event) {
- // return connection to the pool
- PooledConnection closedConn = (PooledConnection) event.getSource();
+ public PrintWriter getLogWriter() throws java.sql.SQLException {
+ return poolDataSource.getLogWriter();
+ }
- // remove this connection from the list of connections
- // managed by this pool...
- int usedInd = usedPool.indexOf(closedConn);
- if (usedInd >= 0) {
- usedPool.remove(usedInd);
- unusedPool.add(closedConn);
- }
- // else ....
- // other possibility is that this is a bad connection, so just ignore its closing event,
- // since it was unregistered in "connectionErrorOccurred"
- }
+ public void setLogWriter(PrintWriter out) throws java.sql.SQLException {
+ poolDataSource.setLogWriter(out);
+ }
- /**
- * Removes connection with an error from the pool. This method
- * is called by PoolManager connections on connection errors
- * to notify PoolManager that connection is in invalid state.
- */
- public synchronized void connectionErrorOccurred(ConnectionEvent event) {
- // later on we should analize the error to see if this
- // is fatal... right now just kill this PooledConnection
+ /** Returns closed connection to the pool. */
+ public synchronized void connectionClosed(ConnectionEvent event) {
+ // return connection to the pool
+ PooledConnection closedConn = (PooledConnection) event.getSource();
- PooledConnection errorSrc = (PooledConnection) event.getSource();
+ // remove this connection from the list of connections
+ // managed by this pool...
+ int usedInd = usedPool.indexOf(closedConn);
+ if (usedInd >= 0) {
+ usedPool.remove(usedInd);
+ unusedPool.add(closedConn);
+ }
+ // else ....
+ // other possibility is that this is a bad connection, so just ignore its closing event,
+ // since it was unregistered in "connectionErrorOccurred"
+ }
- // remove this connection from the list of connections
- // managed by this pool...
+ /**
+ * Removes connection with an error from the pool. This method
+ * is called by PoolManager connections on connection errors
+ * to notify PoolManager that connection is in invalid state.
+ */
+ public synchronized void connectionErrorOccurred(ConnectionEvent event) {
+ // later on we should analize the error to see if this
+ // is fatal... right now just kill this PooledConnection
- int usedInd = usedPool.indexOf(errorSrc);
- if (usedInd >= 0)
- usedPool.remove(usedInd);
- else {
- int unusedInd = unusedPool.indexOf(errorSrc);
- if (unusedInd >= 0)
- unusedPool.remove(unusedInd);
- }
+ PooledConnection errorSrc = (PooledConnection) event.getSource();
- // do not close connection,
- // let the code that catches the exception handle it
- // ....
- }
+ // remove this connection from the list of connections
+ // managed by this pool...
+
+ int usedInd = usedPool.indexOf(errorSrc);
+ if (usedInd >= 0) {
+ usedPool.remove(usedInd);
+ }
+ else {
+ int unusedInd = unusedPool.indexOf(errorSrc);
+ if (unusedInd >= 0)
+ unusedPool.remove(unusedInd);
+ }
+
+ // do not close connection,
+ // let the code that catches the exception handle it
+ // ....
+ }
}
|