一个连接池的例子(来自JIVE)(3)
发表于:2007-07-01来源:作者:点击数:
标签:
//文件:DbConnectionDefaultPool. java 的第三部分 /** * Returns the age of a connection -- the time since it was handed out to * an application. */ public long getAge(Connection conn) { // Returns the age of the connection in millisec. int t
//文件:DbConnectionDefaultPool.
java的第三部分
/**
* Returns the age of a connection -- the time since it was handed out to
* an application.
*/
public long getAge(Connection conn) { // Returns the age of the connection in millisec.
int thisconn = idOfConnection(conn);
return System.currentTimeMillis() - connLockTime[thisconn];
}
private void createConn(int i) throws
SQLException {
Date now = new Date();
try {
Class.forName (dbDriver);
Properties dbProp = new Properties();
//log.println("Creating.....");
dbProp.put("user", dbLogin);
dbProp.put("password", dbPassword);
dbProp.put("characterEncoding","gb2112");
//dbProp.put("useUnicode", "true");
connPool[i] = DriverManager.getConnection
(dbServer,dbProp);
//log.println("Created Ok...");
connStatus[i]=0;
connID[i]=connPool[i].toString();
connLockTime[i]=0;
connCreateDate[i] = now.getTime();
}
catch (ClassNotFoundException e2) {}
log.println(now.toString() + " Opening connection " + String.valueOf(i) +
" " + connPool[i].toString() + ":");
}
/**
* Shuts down the housekeeping thread and closes all connections
* in the pool. Call this method from the destroy() method of the servlet.
*/
/**
* Multi-phase shu
tdown. having following sequence:
* <OL>
* <LI><code>getConnection()</code> will refuse to return connections.
* <LI>The housekeeping thread is shut down.<br>
* Up to the time of <code>millis</code> milliseconds after shutdown of
* the housekeeping thread, <code>freeConnection()</code> can still be
* called to return used connections.
* <LI>After <code>millis</code> milliseconds after the shutdown of the
* housekeeping thread, all connections in the pool are closed.
* <LI>If any connections were in use while being closed then a
* <code>SQLException</code> is thrown.
* <LI>The log is closed.
* </OL><br>
* Call this method from a servlet destroy() method.
*
* @param millis the time to wait in milliseconds.
* @exception SQLException if connections were in use after
* <code>millis</code>.
*/
public void destroy(int millis) throws SQLException {
// Checking for invalid negative arguments is not necessary,
// Thread.join() does this a
lready in runner.join().
// Stop issuing connections
available=false;
// Shut down the background housekeeping thread
runner.inter
rupt();
// Wait until the housekeeping thread has died.
try { runner.join(millis); }
catch(InterruptedException e){} // ignore
// The housekeeping thread could still be running
// (e.g. if millis is too small). This case is ignored.
// At worst, this method will throw an exception with the
// clear indication that the timeout was too short.
long startTime=System.currentTimeMillis();
// Wait for freeConnection() to return any connections
// that are still used at this time.
int useCount;
while((useCount=getUseCount())>0 && System.currentTimeMillis() - startTime <= millis) {
try { Thread.sleep(500); }
catch(InterruptedException e) {} // ignore
}
// Close all connections, whether safe or not
for(int i=0; i < currConnections; i++) {
try {
connPool[i].close();
}
catch (SQLException e1)
{
log.println("Cannot close connections on Destroy");
}
}
if(useCount > 0) {
//bt-test su
clearcase/" target="_blank" >ccessful
String msg="Unsafe shutdown: Had to close "+useCount+
" active DB connections after "+millis+"ms";
log.println(msg);
// Close all open files
log.close();
// Throwing following Exception is essential because servlet authors
// are likely to have their own error logging requirements.
throw new SQLException(msg);
}
// Close all open files
log.close();
}//End destroy()
/**
* Less safe shutdown. Uses default timeout value.
* This method simply calls the <code>destroy()</code> method
* with a <code>millis</code>
* value of 10000 (10 seconds) and ignores <code>SQLException</code>
* thrown by that method.
* @see #destroy(int)
*/
public void destroy() {
try {
destroy(10000);
}
catch(SQLException e) {}
}
/**
* Returns the number of connections in use.
*/
// This method could be reduced to return a counter that is
// maintained by all methods that update connStatus.
// However, it is more efficient to do it this way because:
// Updating the counter would put an additional burden on the most
// frequently used methods; in comparison, this method is
// rarely used (although essential).
public int getUseCount() {
int useCount=0;
synchronized(connStatus) {
for(int i=0; i < currConnections; i++) {
if(connStatus[i] > 0) { // In use
useCount++;
}
}
}
return useCount;
}//End getUseCount()
/**
* Returns the number of connections in the dynamic pool.
*/
public int getSize() {
return currConnections;
}//End getSize()
}
/**
* An implementation of the Connection interface that wraps an underlying
* Connection object. It releases the connection back to a connection pool
* when Connection.close() is called.
*/
public class ConnectionWrapper implements Connection {
private Connection connection;
private ConnectionPool connectionPool;
public ConnectionWrapper(Connection connection, ConnectionPool connectionPool) {
this.connection = connection;
this.connectionPool = connectionPool;
}
/**
* Instead of closing the underlying connection, we simply release
* it back into the pool.
*/
public void close() throws SQLException {
connectionPool.freeConnection(this.connection);
//Release object references. Any further method calls on the
//connection will fail.
connection = null;
connectionPool = null;
}
public Statement createStatement() throws SQLException {
return connection.createStatement();
}
public PreparedStatement prepareStatement(String
sql) throws SQLException {
return connection.prepareStatement(sql);
}
public CallableStatement prepareCall(String sql) throws SQLException {
return connection.prepareCall(sql);
}
public String nativeSQL(String sql) throws SQLException {
return connection.nativeSQL(sql);
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
connection.setAutoCommit(autoCommit);
}
public boolean getAutoCommit() throws SQLException {
return connection.getAutoCommit();
}
public void commit() throws SQLException {
connection.commit();
}
public void rollback() throws SQLException {
connection.rollback();
}
public boolean isClosed() throws SQLException {
return connection.isClosed();
}
public DatabaseMetaData getMetaData() throws SQLException {
return connection.getMetaData();
}
public void setReadOnly(boolean readOnly) throws SQLException {
connection.setReadOnly(readOnly);
}
public boolean isReadOnly() throws SQLException {
return connection.isReadOnly();
}
public void setCatalog(String catalog) throws SQLException {
connection.setCatalog(catalog);
}
public String getCatalog() throws SQLException {
return connection.getCatalog();
}
public void setTransactionIsolation(int level) throws SQLException {
connection.setTransactionIsolation(level);
}
public int getTransactionIsolation() throws SQLException {
return connection.getTransactionIsolation();
}
public SQLWarning getWarnings() throws SQLException {
return connection.getWarnings();
}
public void clearWarnings() throws SQLException {
connection.clearWarnings();
}
public Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException
{
return connection.createStatement(resultSetType, resultSetConcurrency);
}
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException
{
return connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
}
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException
{
return prepareCall(sql, resultSetType, resultSetConcurrency);
}
public Map getTypeMap() throws SQLException {
return connection.getTypeMap();
}
public void setTypeMap(Map map) throws SQLException {
connection.setTypeMap(map);
}
}
}
原文转自:http://www.ltesting.net