数据库连接池连接复用原理

HikariCP的ProxyConnection类有如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// **********************************************************************
// "Overridden" java.sql.Connection Methods
// **********************************************************************

/** {@inheritDoc} */
@Override
public final void close() throws SQLException
{

// Closing statements can cause connection eviction, so this must run before the conditional below
closeStatements();

if (delegate != ClosedConnection.CLOSED_CONNECTION) {
leakTask.cancel();

try {
if (isCommitStateDirty && !isAutoCommit) {
delegate.rollback();
lastAccess = currentTime();
LOGGER.debug("{} - Executed rollback on connection {} due to dirty commit state on close().", poolEntry.getPoolName(), delegate);
}

if (dirtyBits != 0) {
// 重置catalog、schema、sReadOnly、AutoCommit、transactionIsolation、NetworkTimeout这些属性
poolEntry.resetConnectionState(this, dirtyBits);
lastAccess = currentTime();
}

delegate.clearWarnings();
}
catch (SQLException e) {
// when connections are aborted, exceptions are often thrown that should not reach the application
if (!poolEntry.isMarkedEvicted()) {
throw checkException(e);
}
}
finally {
delegate = ClosedConnection.CLOSED_CONNECTION;
//PoolEntry会被设为STATE_NOT_IN_USE,PoolEntry保存了Connection
poolEntry.recycle(lastAccess);
}
}
}

从上代码可知,ProxyConnection重写了Connection的Close方法,在我们结合spring调用完如数据库查询会调用connection.close(),但是ProxyConnection并不会真正去关闭连接,而是重置该连接的状态,使得该连接可以继续被使用。