📄 newpooledconnection.java
字号:
physicalConnection.setTransactionIsolation( dflt_txn_isolation ); isolation_lvl_nondefault = false; //System.err.println("reset txn isolation: " + dflt_txn_isolation); } if (catalog_nondefault) { physicalConnection.setCatalog( dflt_catalog ); catalog_nondefault = false; } if (holdability_nondefault) //this cannot go to true if holdability is not supported, so we don't have to check. { physicalConnection.setHoldability( dflt_holdability ); holdability_nondefault = false; } if (readOnly_nondefault) { physicalConnection.setReadOnly( dflt_readOnly ); readOnly_nondefault = false; } if (typeMap_nondefault) { physicalConnection.setTypeMap( dflt_typeMap ); typeMap_nondefault = false; } } synchronized boolean isStatementCaching() { return scache != null; } synchronized SQLException handleThrowable( Throwable t ) { if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER )) logger.log( MLevel.FINER, this + " handling a throwable.", t ); SQLException sqle = SqlUtils.toSQLException( t ); //logger.warning("handle throwable ct: " + connectionTester); int status = connectionTester.statusOnException( physicalConnection, sqle ); updateConnectionStatus( status ); if (status != ConnectionTester.CONNECTION_IS_OKAY) { if (Debug.DEBUG) {// System.err.print(this + " invalidated by Exception: ");// t.printStackTrace(); if ( logger.isLoggable( MLevel.FINE ) ) logger.log(MLevel.FINE, this + " invalidated by Exception.", t); } /* ------ A users have complained that SQLExceptions ought not close their Connections underneath them under any circumstance. Signalling the Connection error after updating the Connection status should be sufficient from the pool's perspective, because the PooledConnection will be marked broken by the pool and will be destroyed on checkin. I think actually close()ing the Connection when it appears to be broken rather than waiting for users to close() it themselves is overly aggressive, so I'm commenting the old behavior out. The only potential downside to this approach is that users who do not close() in a finally clause properly might see their close()es skipped by exceptions that previously would have led to automatic close(). But relying on the automatic close() was never reliable (since it only ever happened when c3p0 determined a Connection to be absolutely broken), and is generally speaking a client error that c3p0 ought not be responsible for dealing with. I think it's right to leave this out. -- swaldman 2004-12-09 ------ try { close( t ); } catch (SQLException e) { e.printStackTrace(); throw new InternalError("C3P0 Error: NewPooledConnection's private close() method should " + "suppress any Exceptions if a throwable cause is provided."); } */ if (! connection_error_signaled) { ces.fireConnectionErrorOccurred( sqle ); connection_error_signaled = true; } else {// System.err.println("[c3p0] Warning: PooledConnection that has already signalled a Connection error is still in use!");// System.err.println("[c3p0] Another error has occurred [ " + t + " ] which will not be reported to listeners!"); if ( logger.isLoggable( MLevel.WARNING ) ) { logger.log(MLevel.WARNING, "[c3p0] A PooledConnection that has already signalled a Connection error is still in use!"); logger.log(MLevel.WARNING, "[c3p0] Another error has occurred [ " + t + " ] which will not be reported to listeners!", t); } } } return sqle; } // private methods private void fireConnectionClosed() { exposedProxy = null; ces.fireConnectionClosed(); } private void fireConnectionErrorOccurred(SQLException error) { ces.fireConnectionErrorOccurred( error ); } // methods below must be called from sync'ed methods /* * If a throwable cause is provided, the PooledConnection is known to be broken (cause is an invalidating exception) * and this method will not throw any exceptions, even if some resource closes fail. * * If cause is null, then we think the PooledConnection is healthy, and we will report (throw) an exception * if resources unexpectedlay fail to close. */ private void close( Throwable cause ) throws SQLException { if ( this.invalidatingException == null ) { List closeExceptions = new LinkedList(); // cleanup ResultSets cleanupResultSets( closeExceptions ); // cleanup uncached Statements cleanupUncachedStatements( closeExceptions ); // cleanup cached Statements try { closeAllCachedStatements(); } catch ( SQLException e ) { closeExceptions.add(e); } // cleanup physicalConnection try { physicalConnection.close(); } catch ( SQLException e ) { if (logger.isLoggable( MLevel.FINER )) logger.log( MLevel.FINER, "Failed to close physical Connection: " + physicalConnection, e ); closeExceptions.add(e); } // update our state to bad status and closed, and log any exceptions if ( connection_status == ConnectionTester.CONNECTION_IS_OKAY ) connection_status = ConnectionTester.CONNECTION_IS_INVALID; if ( cause == null ) { this.invalidatingException = new SQLException(this + " explicitly closed!"); logCloseExceptions( null, closeExceptions ); if (closeExceptions.size() > 0) throw new SQLException("Some resources failed to close properly while closing " + this); } else { this.invalidatingException = cause; if (Debug.TRACE >= Debug.TRACE_MED) logCloseExceptions( cause, closeExceptions ); else logCloseExceptions( cause, null ); } } } private void cleanupResultSets( List closeExceptions ) { cleanupAllStatementResultSets( closeExceptions ); cleanupUnclosedResultSetsSet( metaDataResultSets, closeExceptions ); if ( rawConnectionResultSets != null ) cleanupUnclosedResultSetsSet( rawConnectionResultSets, closeExceptions ); } private void cleanupUnclosedResultSetsSet( Set rsSet, List closeExceptions ) { for ( Iterator ii = rsSet.iterator(); ii.hasNext(); ) { ResultSet rs = (ResultSet) ii.next(); try { rs.close(); } catch ( SQLException e ) { closeExceptions.add(e); } ii.remove(); } } private void cleanupStatementResultSets( Statement stmt ) { Set rss = resultSets( stmt, false ); if ( rss != null ) { for ( Iterator ii = rss.iterator(); ii.hasNext(); ) { try { ((ResultSet) ii.next()).close(); } catch ( Exception e ) {// System.err.print("ResultSet close() failed: ");// e.printStackTrace(); if ( logger.isLoggable( MLevel.INFO ) ) logger.log(MLevel.INFO, "ResultSet close() failed.", e); } } } resultSetsForStatements.remove( stmt ); } private void cleanupAllStatementResultSets( List closeExceptions ) { for ( Iterator ii = resultSetsForStatements.keySet().iterator(); ii.hasNext(); ) { Object stmt = ii.next(); Set rss = (Set) resultSetsForStatements.get( stmt ); for (Iterator jj = rss.iterator(); jj.hasNext(); ) { ResultSet rs = (ResultSet) jj.next(); try { rs.close(); } catch ( SQLException e ) { closeExceptions.add(e); } } } resultSetsForStatements.clear(); } private void cleanupUncachedStatements( List closeExceptions ) { for ( Iterator ii = uncachedActiveStatements.iterator(); ii.hasNext(); ) { Statement stmt = (Statement) ii.next(); try { stmt.close(); } catch ( SQLException e ) { closeExceptions.add(e); } ii.remove(); } } private void checkinAllCachedStatements( List closeExceptions ) { try { if (scache != null) scache.checkinAll( physicalConnection ); } catch ( SQLException e ) { closeExceptions.add(e); } } private void closeAllCachedStatements() throws SQLException { if (scache != null) scache.closeAll( physicalConnection ); } private void updateConnectionStatus(int status) { switch ( this.connection_status ) { case ConnectionTester.DATABASE_IS_INVALID: //can't get worse than this, do nothing. break; case ConnectionTester.CONNECTION_IS_INVALID: if (status == ConnectionTester.DATABASE_IS_INVALID) this.connection_status = status; break; case ConnectionTester.CONNECTION_IS_OKAY: if (status != ConnectionTester.CONNECTION_IS_OKAY) this.connection_status = status; break; default: throw new InternalError(this + " -- Illegal Connection Status: " + this.connection_status); } } private Set resultSets( Statement stmt, boolean create ) { Set out = (Set) resultSetsForStatements.get( stmt ); if ( out == null && create ) { out = new HashSet(); resultSetsForStatements.put( stmt, out ); } return out; } // static utility functions private static void logCloseExceptions( Throwable cause, Collection exceptions ) { if ( logger.isLoggable( MLevel.INFO ) ) { if (cause != null) { // System.err.println("[c3p0] A PooledConnection died due to the following error!"); // cause.printStackTrace(); logger.log(MLevel.INFO, "[c3p0] A PooledConnection died due to the following error!", cause); } if ( exceptions != null && exceptions.size() > 0) { if ( cause == null ) logger.info("[c3p0] Exceptions occurred while trying to close a PooledConnection's resources normally."); //System.err.println("[c3p0] The following Exceptions occurred while trying to close a PooledConnection's resources normally."); else logger.info("[c3p0] Exceptions occurred while trying to close a Broken PooledConnection."); //System.err.println("[c3p0] The following Exceptions occurred while trying to close a broken PooledConnection."); for ( Iterator ii = exceptions.iterator(); ii.hasNext(); ) { Throwable t = (Throwable) ii.next(); // System.err.print("[c3p0 -- close Exception]: "); // t.printStackTrace(); logger.log(MLevel.INFO, "[c3p0] NewPooledConnection close Exception.", t); } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -