Druid version 1.2.12 released, new connection pool default configuration connectTimeout and socketTimeout detailed explanation

The features of the new version are as follows

This version of the connection pool adds configuration connectTimeout and socketTimeout by default, and enhances SQL Parser

  1. The connection pool DruidDataSource supports new configurations connectTimeout and socketTimeout, both of which are 10 seconds. This default value will reduce the failure of the connection pool to create connections due to network packet loss.
  2. Fix the problem of incorrect logic in determining whether to close the connection pool DruidDataSource#handleFatalError method #4724
  3. Fix the problem that StatFilter statistics Statement only records the first SQL when executing SQL #4921
  4. Fix the problem of incorrect ParameterizedOutputVisitorUtils#restore result #4532
  5. SQL Parser enhances support for PolarDB-X #4927
  6. SQL Parser enhances support for Oceanbase #4833
  7. SQL Parser enhances support for MySQL #4916 #4817 #4825
  8. SQL Parser enhances support for Clickhouse #4833 #4881
  9. SQL Parser enhances support for DB2 #4838
  10. SQL Parser enhances support for Oracle
Connection pool connectTimeout configuration

The following code has been added to the source code com.alibaba.druid.pool.DruidAbstractDataSource#createPhysicalConnection() method:

        if (connectTimeout > 0) {
    
    
            if (isMySql) {
    
    
                physicalConnectProperties.put("connectTimeout", connectTimeout);
            } else if (isOracle) {
    
    
                physicalConnectProperties.put("oracle.net.CONNECT_TIMEOUT", connectTimeout);
            } else if (driver != null && "org.postgresql.Driver".equals(driver.getClass().getName())) {
    
    
                physicalConnectProperties.put("loginTimeout", connectTimeout);
                physicalConnectProperties.put("socketTimeout", connectTimeout);
            }
        }

Configure the connection timeout for mysql, oracle, and postgresql database drivers, which takes effect when connecting. Default value: 10000ms

Connection pool socket-timeout configuration

When the database is down or the network is in Yichang, jdbc's socket timeout is necessary. Due to the TCP/IP structure, the socket has no way to detect network errors, so the application cannot detect whether the connection to the database has been disconnected. If there is no socket timeout, the application will wait for the database to return the result. In order to avoid dead connections, the socket must set a timeout. By setting the timeout, you can prevent waiting for network errors and shorten the failure time.

Add the following code to the source code com.alibaba.druid.pool.DruidAbstractDataSource#createPhysicalConnection():

            if (socketTimeout > 0 && !netTimeoutError) {
    
    
                try {
    
    
                  //默认sql执行10s
                    conn.setNetworkTimeout(netTimeoutExecutor, socketTimeout);
                } catch (SQLFeatureNotSupportedException | AbstractMethodError e) {
    
    
                    netTimeoutError = true;
                } catch (Exception ignored) {
    
    
                    // ignored
                }
            }

Where netTimeoutExecutor is an instance object of SynchronousExecutor

    class SynchronousExecutor implements Executor {
    
    
        @Override
        public void execute(Runnable command) {
    
    
            try {
    
    
                command.run();
            } catch (AbstractMethodError error) {
    
    
                netTimeoutError = true;
            } catch (Exception ignored) {
    
    
                if (LOG.isDebugEnabled()) {
    
    
                    LOG.debug("failed to execute command " + command);
                }
            }
        }
    }

SynchronousExecutor is initialized in the com.alibaba.druid.pool.DruidDataSource#init method

The specific implementation of command is com.mysql.cj.jdbc.ConnectionImpl.NetworkTimeoutSetter (the specific implementation of mysql)

    private static class NetworkTimeoutSetter implements Runnable {
    
    
        private final WeakReference<JdbcConnection> connRef;
        private final int milliseconds;

        public NetworkTimeoutSetter(JdbcConnection conn, int milliseconds) {
    
    
            this.connRef = new WeakReference(conn);
            this.milliseconds = milliseconds;
        }

        public void run() {
    
    
            JdbcConnection conn = (JdbcConnection)this.connRef.get();
            if (conn != null) {
    
    
                synchronized(conn.getConnectionMutex()) {
    
    
                    ((NativeSession)conn.getSession()).setSocketTimeout(this.milliseconds);
                }
            }

        }
    }
Connection pool query-timeout, transaction-query-timeout configuration
  • query-timeout: Set the number of seconds for the JDBC driver to execute Statement statements. If the limit is exceeded, SQLTimeoutException will be thrown. Default: 0. Unit: No limit in seconds.
  • transaction-query-timeout: Set the number of seconds for the JDBC driver to execute N Statement statements (transaction mode). If the limit is exceeded, SQLTimeoutException will be thrown. Default: 0 Unit: No limit in seconds

The specific implementation code is as follows in com.alibaba.druid.pool.DruidAbstractDataSource#initStatement:

    void initStatement(DruidPooledConnection conn, Statement stmt) throws SQLException {
    
    
        boolean transaction = !conn.getConnectionHolder().underlyingAutoCommit;

        int queryTimeout = transaction ? getTransactionQueryTimeout() : getQueryTimeout();

        if (queryTimeout > 0) {
    
    
            stmt.setQueryTimeout(queryTimeout);
        }
    }

    public int getTransactionQueryTimeout() {
    
    
        if (transactionQueryTimeout <= 0) {
    
    
            return queryTimeout;
        }

        return transactionQueryTimeout;
    }

    public int getQueryTimeout() {
    
    
        return queryTimeout;
    }
Summarize

After looking at the above time settings, you may be a little confused. How to distinguish between so many times? Let’s first look at the pictures found on the Internet:

Timeout time distinction

High-level timeout depends on low-level timeout. Only when low-level timeout is correct, high-level timeout can ensure normality; for example, when there is a problem with socket timeout, high-level statement timeout and transaction timeout will be invalid. Statement timeout cannot handle the timeout when the network connection fails. All it can do is limit the operation time of the statement. The timeout when the network connection fails must be handled by JDBC. The socket timeout of JDBC will be affected by the socket timeout setting of the operating system.

GitHub address: https://github.com/mingyang66/spring-parent

Guess you like

Origin blog.csdn.net/yaomingyang/article/details/126901144