zoukankan      html  css  js  c++  java
  • com.mchange.v2.c3p0.impl.NewPooledConnection@be1839d closed by a client的正确解答

    关于c3p0在debug模式下控制台抛出的如下异常:

    java.lang.Exception: DEBUG -- CLOSE BY CLIENT STACK TRACE
    at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:566)
    at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:470)
    at com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:964)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

    或者:

    java.lang.Exception: DEBUG -- CLOSE BY CLIENT STACK TRACE
    at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:566)
    at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPoolManager.initializeAutomaticTestTable(C3P0PooledConnectionPoolManager.java:834)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPoolManager.createPooledConnectionPool(C3P0PooledConnectionPoolManager.java:696)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPoolManager.getPool(C3P0PooledConnectionPoolManager.java:257)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPoolManager.getPool(C3P0PooledConnectionPoolManager.java:271)
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getNumThreadsAwaitingCheckoutDefaultUser(AbstractPoolBackedDataSource.java:203)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.mchange.v2.beans.BeansUtils.extractAccessiblePropertiesToMap(BeansUtils.java:359)
    at com.mchange.v2.beans.BeansUtils.appendPropNamesAndValues(BeansUtils.java:324)
    at com.mchange.v2.c3p0.ComboPooledDataSource.toString(ComboPooledDataSource.java:539)
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getPoolManager(AbstractPoolBackedDataSource.java:462)
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
    at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:81)
    at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67)
    at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:279)
    at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:72)
    at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:59)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:267)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:137)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:96)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:77)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:108)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:102)

    通常在日志中包含上述信息之后,其紧接着的上下面会包含类似如下信息:

    17-03-08 16:37:00 DEBUG com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2 com.mchange.v2.resourcepool.BasicResourcePool: Preparing to destroy resource: com.mchange.v2.c3p0.impl.NewPooledConnectio
    n@1070779f
    17-03-08 16:37:00 DEBUG com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2 com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool: Preparing to destroy PooledConnection: com.mchange.v2.c3p0.impl.NewPoo
    ledConnection@1070779f

    17-03-08 16:37:00 DEBUG com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2 com.mchange.v2.c3p0.impl.NewPooledConnection: com.mchange.v2.c3p0.impl.NewPooledConnection@1070779f closed by a client.
    java.lang.Exception: DEBUG -- CLOSE BY CLIENT STACK TRACE
    at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:566)
    at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:470)
    at com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:964)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
    17-03-08 16:37:00 DEBUG com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2 com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool: Successfully destroyed PooledConnection: com.mchange.v2.c3p0.impl.NewP
    ooledConnection@1070779f
    17-03-08 16:37:00 DEBUG com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2 com.mchange.v2.resourcepool.BasicResourcePool: Successfully destroyed resource: com.mchange.v2.c3p0.impl.NewPooledConnect
    ion@1070779f

    比如initializeAutomaticTestTable处源码为:

        // only called from sync'ed methods
        private String initializeAutomaticTestTable(String automaticTestTable, DbAuth auth) throws SQLException
        {
            PooledConnection throwawayPooledConnection =    auth.equals( defaultAuth ) ? 
                                                            cpds.getPooledConnection() : 
                                                            cpds.getPooledConnection(auth.getUser(), auth.getPassword()); 
            Connection c = null;
            PreparedStatement testStmt = null;
            PreparedStatement createStmt = null;
            ResultSet mdrs = null;
            ResultSet rs = null;
            boolean exists;
            boolean has_rows;
            String out;
            try
            {
                c = throwawayPooledConnection.getConnection();
    
                DatabaseMetaData dmd = c.getMetaData();
                String q = dmd.getIdentifierQuoteString();
                String quotedTableName = q + automaticTestTable + q;
                out = "SELECT * FROM " + quotedTableName;
                mdrs = dmd.getTables( null, null, automaticTestTable, new String[] {"TABLE"} );
                exists = mdrs.next();
    
                //System.err.println("Table " + automaticTestTable + " exists? " + exists);
    
                if (exists)
                {
                    testStmt = c.prepareStatement( out );
                    rs = testStmt.executeQuery();
                    has_rows = rs.next();
                    if (has_rows)
                        throw new SQLException("automatic test table '" + automaticTestTable + 
                                        "' contains rows, and it should not! Please set this " +
                                        "parameter to the name of a table c3p0 can create on its own, " +
                        "that is not used elsewhere in the database!");
                }
                else
                {
                    String createSql = "CREATE TABLE " + quotedTableName + " ( a CHAR(1) )";
                    try
                    {
                        createStmt = c.prepareStatement( createSql );
                        createStmt.executeUpdate();
                    }
                    catch (SQLException e)
                    {
                        if (logger.isLoggable( MLevel.WARNING ))
                            logger.log(MLevel.WARNING, 
                                            "An attempt to create an automatic test table failed. Create SQL: " +
                                            createSql,
                                            e );
                        throw e;
                    }
                }
                return out;
            }
            finally
            { 
                ResultSetUtils.attemptClose( mdrs );
                ResultSetUtils.attemptClose( rs );
                StatementUtils.attemptClose( testStmt );
                StatementUtils.attemptClose( createStmt );
                ConnectionUtils.attemptClose( c ); 
                try{ if (throwawayPooledConnection != null) throwawayPooledConnection.close(); }
                catch ( Exception e ) 
                { 
                    //e.printStackTrace(); 
                    logger.log(MLevel.WARNING, "A PooledConnection failed to close.", e);
                }
            }
        }

    可知,它是被开发人员有意关闭的。

    比如上面的close原因是idle超过时间,还有初始化c3p0test表后该连接主动关闭,当然还可能有其他原因。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 = NORMAL_CLOSE_PLACEHOLDER;
    
                    if ( logger.isLoggable( MLevel.FINEST ) )
                        logger.log( MLevel.FINEST, this + " closed by a client.", new Exception("DEBUG -- CLOSE BY CLIENT STACK TRACE") );
    
                    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 );
                }
            }
        }

    从上面的流程+日志,我们也可确定它是被有意关闭的。所以确定c3p0的这些日志原因和作用还是要通过上下文代码来理解。在看之前,网上搜了一遍,讲得目的不对马嘴,就像一个中学生问“如何才能英语考高分”,你却回答人家“为什么要学英语”。

  • 相关阅读:
    Delphi Excel 操作大全
    ThreadLocal类
    MyBatis实战总结
    MyBatis入门
    Mybatis逆向工程
    2020年全国高校计算机能力挑战赛初赛java组
    集合论基础
    命题与逻辑
    Redis技术概述
    UML图中6种箭头的含义
  • 原文地址:https://www.cnblogs.com/zhjh256/p/6520333.html
Copyright © 2011-2022 走看看