📄 jdbcdatasource.java
字号:
//Let this pass through... throw ce; } catch(Exception e) { throw new ConfigurationException("Error configuring JdbcDataSource", e); } } /** * The dispose operation is called at the end of a components lifecycle. * Cleans up all JDBC connections. * * @throws Exception if an error is encountered during shutdown */ public void dispose() { // Stop the background monitoring thread if(reaper != null) { reaperActive = false; //In case it's sleeping, help it quit faster reaper.interrupt(); reaper = null; } // The various entries will finalize themselves once the reference // is removed, so no need to do it here } /** * Close all connections. The connection pooler will recreate these connections if something * starts requesting them again. * * @deprecated This was left over code from Town... but not exposed in Avalon. */ public void killAllConnections() { //Just remove the references to all the connections... this will cause them to get // finalized before very long. (not an instant shutdown, but that's ok). synchronized (pool) { pool.clear(); } } /** * Implements the ConnDefinition behavior when something bad has happened to a connection. If a * sql command was provided in the properties file, it will run this and attempt to determine * whether the connection is still valid. If it is, it recycles this connection back into the * pool. If it is not, it closes the connection. * * @param entry the connection that had problems * @deprecated - No longer used in the new approach. */ public void killConnection(PoolConnEntry entry) { if(entry != null) { // if we were provided SQL to test the connection with, we will use // this and possibly just release the connection after clearing warnings if(verifyConnSQL != null) { try { // Test this connection java.sql.Statement stmt = null; try { stmt = entry.createStatement(); stmt.execute(verifyConnSQL); } finally { try { if (stmt != null) { stmt.close(); } } catch (SQLException sqle) { // Failure to close ignored on test connection } } // Passed test... recycle the entry entry.unlock(); } catch(SQLException e1) { // Failed test... close the entry finalizeEntry(entry); } } else { // No SQL was provided... we have to kill this entry to be sure finalizeEntry(entry); } return; } else { if (getLogger().isWarnEnabled()) { getLogger().warn("----> Could not find connection to kill!!!"); } return; } } /** * Implements the ConnDefinition behavior when a connection is no longer needed. This resets * flags on the wrapper of the connection to allow others to use this connection. * * @param entry */ public void releaseConnection(PoolConnEntry entry) { //PoolConnEntry entry = findEntry(conn); if(entry != null) { entry.unlock(); return; } else { if (getLogger().isWarnEnabled()) { getLogger().warn("----> Could not find the connection to free!!!"); } return; } } /** * Background thread that checks if there are fewer connections open than minConn specifies, * and checks whether connections have been checked out for too long, killing them. */ public void run() { try { while(reaperActive) { synchronized(pool) { for(int i = 0; i < pool.size(); i++) try { PoolConnEntry entry = (PoolConnEntry)pool.get(i); long age = System.currentTimeMillis() - entry.getLastActivity(); synchronized(entry) { if((entry.getStatus() == PoolConnEntry.ACTIVE) && (age > ACTIVE_CONN_HARD_TIME_LIMIT)) { StringBuffer logBuffer = new StringBuffer(128) .append(" ***** connection ") .append(entry.getId()) .append(" is way too old: ") .append(age) .append(" > ") .append(ACTIVE_CONN_HARD_TIME_LIMIT) .append(" and will be closed."); getLogger().info(logBuffer.toString()); // This connection is way too old... // kill it no matter what finalizeEntry(entry); continue; } if((entry.getStatus() == PoolConnEntry.ACTIVE) && (age > ACTIVE_CONN_TIME_LIMIT)) { StringBuffer logBuffer = new StringBuffer(128) .append(" ***** connection ") .append(entry.getId()) .append(" is way too old: ") .append(age) .append(" > ") .append(ACTIVE_CONN_TIME_LIMIT); getLogger().info(logBuffer.toString()); // This connection is way too old... // just log it for now. continue; } if((entry.getStatus() == PoolConnEntry.AVAILABLE) && (age > CONN_IDLE_LIMIT)) { //We've got a connection that's too old... kill it finalizeEntry(entry); continue; } } } catch (Throwable ex) { StringWriter sout = new StringWriter(); PrintWriter pout = new PrintWriter(sout, true); pout.println("Reaper Error: "); ex.printStackTrace(pout); if (getLogger().isErrorEnabled()) { getLogger().error(sout.toString()); } } } try { // Check for activity every 5 seconds Thread.sleep(5000L); } catch(InterruptedException ex) { } } } finally { Thread.currentThread().interrupted(); } } protected void debug(String message) { getLogger().debug(message); } protected void info(String message) { getLogger().info(message); } /* * This is a real hack, but oh well for now */ protected void warn(String message) { getLogger().warn(message); } /** * Creates a new connection as per these properties, adds it to the pool, and logs the creation. * * @return PoolConnEntry the new connection wrapped as an entry * @throws SQLException */ private PoolConnEntry createConn() throws SQLException { PoolConnEntry entry = null; synchronized(pool) { if(connCreationsInProgress > 0) { //We are already creating one in another place return null; } long now = System.currentTimeMillis(); if((now - connLastCreated) < (1000 * pool.size())) { //We don't want to scale up too quickly... if(DEEP_DEBUG) { System.err.println("We don't want to scale up too quickly"); } return null; } if((maxConn == 0) || (pool.size() < maxConn)) { connCreationsInProgress++; connLastCreated = now; } else { // We've already hit a limit... fail silently if (getLogger().isDebugEnabled()) { StringBuffer logBuffer = new StringBuffer(128) .append("Connection limit hit... ") .append(pool.size()) .append(" in pool and ") .append(connCreationsInProgress) .append(" + on the way."); getLogger().debug(logBuffer.toString()); } return null; } try { entry = new PoolConnEntry(this, java.sql.DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword), ++connectionCount); if (getLogger().isDebugEnabled()) { getLogger().debug("Opening connection " + entry); } entry.lock(); pool.add(entry); return entry; } catch(SQLException sqle) { //Shouldn't ever happen, but it did, just return null. // Exception from DriverManager.getConnection() - log it, and return null StringWriter sout = new StringWriter(); PrintWriter pout = new PrintWriter(sout, true); pout.println("Error creating connection: "); sqle.printStackTrace(pout); if (getLogger().isErrorEnabled()) { getLogger().error(sout.toString()); } return null; } finally { connCreationsInProgress--; } } } /** * Closes a connection and removes it from the pool. * * @param entry entry */ private void finalizeEntry(PoolConnEntry entry) { synchronized(pool) { try { entry.finalize(); } catch(Exception fe) { } pool.remove(entry); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -