새로운 버전의 특징은 다음과 같습니다
이 버전의 연결 풀은 기본적으로 connectTimeout 및 SocketTimeout 구성을 추가하고 SQL 구문 분석기를 향상시킵니다.
- 연결 풀 DruidDataSource는 새로운 구성인 connectTimeout과 SocketTimeout을 지원하며 둘 다 10초입니다. 이 기본값은 네트워크 패킷 손실로 인해 연결 풀이 연결을 생성하지 못하는 것을 줄여줍니다.
- 연결 풀을 닫을지 여부를 결정할 때 잘못된 논리 문제 수정 DruidDataSource#handleFatalError 메서드 #4724
- StatFilter 통계 명령문이 SQL 실행 시 첫 번째 SQL만 기록하는 문제 수정 #4921
- 잘못된 ParameterizedOutputVisitorUtils#restore 결과 문제 수정 #4532
- SQL Parser는 PolarDB-X #4927 에 대한 지원을 강화합니다.
- SQL Parser는 Oceanbase #4833 에 대한 지원을 강화합니다.
- SQL Parser는 MySQL #4916 #4817 #4825 에 대한 지원을 강화합니다.
- SQL Parser는 Clickhouse #4833 #4881 에 대한 지원을 강화합니다.
- SQL Parser는 DB2 #4838 에 대한 지원을 강화합니다.
- SQL Parser는 Oracle에 대한 지원을 강화합니다.
연결 풀 connectTimeout 구성
다음 코드가 소스 코드 com.alibaba.druid.pool.DruidAbstractDataSource#createPhysicalConnection() 메서드에 추가되었습니다.
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);
}
}
연결 시 적용되는 mysql, oracle 및 postgresql 데이터베이스 드라이버에 대한 연결 시간 제한을 구성합니다. 기본값: 10000ms
연결 풀 소켓 시간 초과 구성
데이터베이스가 다운되거나 네트워크가 이창에 있는 경우 jdbc의 소켓 타임아웃이 필요하지만 TCP/IP 구조상 소켓에서는 네트워크 오류를 감지할 수 있는 방법이 없으므로 애플리케이션에서는 데이터베이스에 대한 연결이 끊겼는지 여부를 감지할 수 없습니다. . 소켓 시간 초과가 없으면 애플리케이션은 데이터베이스가 결과를 반환할 때까지 기다립니다. 연결 끊김 현상을 방지하기 위해서는 소켓에서 타임아웃을 설정해야 하는데, 타임아웃을 설정하면 네트워크 오류를 기다리는 것을 방지하고 실패 시간을 단축할 수 있습니다.
소스 코드 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
}
}
netTimeoutExecutor는 동기식 실행기의 인스턴스 객체입니다.
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);
}
}
}
}
동기 실행기는 com.alibaba.druid.pool.DruidDataSource#init 메소드에서 초기화됩니다.
명령의 구체적인 구현은 com.mysql.cj.jdbc.ConnectionImpl.NetworkTimeoutSetter(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);
}
}
}
}
연결 풀 쿼리 시간 초과, 트랜잭션 쿼리 시간 초과 구성
- query-timeout: JDBC 드라이버가 명령문을 실행하는 데 걸리는 시간(초)을 설정합니다. 제한을 초과하면 SQLTimeoutException이 발생합니다. 기본값: 0. 단위: 초 단위 제한 없음.
- transaction-query-timeout: JDBC 드라이버가 N개의 문 문을 실행하는 데 필요한 초 수를 설정합니다(트랜잭션 모드). 제한을 초과하면 SQLTimeoutException이 발생합니다. 기본값: 0 단위: 초 단위 제한 없음
구체적인 구현 코드는 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;
}
요약하다
위의 시간 설정을 보면 약간 혼란스러울 수 있습니다. 이렇게 많은 시간을 어떻게 구별할 수 있습니까? 먼저 인터넷에 있는 사진을 살펴보겠습니다.
상위 레벨 타임아웃은 하위 레벨 타임아웃에 따라 달라지며, 하위 레벨 타임아웃이 올바른 경우에만 상위 레벨 타임아웃이 정상성을 보장할 수 있습니다. 유효하지 않은. 명령문 시간 초과는 네트워크 연결 실패 시 시간 초과를 처리할 수 없으며 명령문의 작업 시간을 제한할 수 있습니다. 네트워크 연결 실패 시 시간 초과는 JDBC에서 처리해야 합니다. JDBC의 소켓 시간 초과는 소켓 시간 초과의 영향을 받습니다. 운영 체제 설정.
GitHub 주소: https://github.com/mingyang66/spring-parent