This article has participated in the activity of “New person creation Ceremony”, and started the road of digging gold creation together

DruidDataSource is one of DruidCP’s most important classes. It is used to start and close connection pools, and to retrieve and manage connections. Its internal key data structure is shown in the following table:

name type instructions
connections volatile DruidConnectionHolder[] Pool key array, which holds connections, is actually DruidConnectionHolder array. Connection is held by DruidConnectionHolder
evictConnections DruidConnectionHolder[] The pool of a Connection that is expelled is entered into this array after invoking the shrink method shrink.
keepAliveConnections DruidConnectionHolder[] In the shrink method, all connections that satisfy the Keepalive state enter this array.
autoFilters static List This list stores all filters
enable volatile boolean The default value is true, indicating whether the connection pool is available. Call the close method to set this value to false. When this value is false, the number of connection errors increases by 1, and get connections or other operations fail.
inited volatile boolean The default value is false, indicating completion of initialization.
closing volatile boolean Status during shutdown. Is close
closed volatile boolean Close the completed state.

The most critical data structure for the connection pool is the array that holds the DruidConnectionHolder internally, connections. DruidConnectionHolder’s data structure is:

name type instructions
dataSource final DruidAbstractDataSource A pointer to a DataSource.
conn final Connection Points to a real database connection, implemented by a database driver.
connectionId final long Connection number.
connectionEventListeners final List Connect event listeners.
statementEventListeners final List Statement event listener.
statementPool PreparedStatementPool Inside it is a LRUCache that caches the Statement.
statementTrace final List A list of statements to trace. The purpose of this statementTrace will be explored in more detail later.

DruidConnectionHolder DruidConnectionHolder DruidConnectionHolder DruidConnectionHolder DruidConnectionHolder DruidPooledConnection

Public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {// Execute init(); // If filter exists, execute filter to get the connection through filter's proxy class. If (filter.size () > 0) {// Filter chain FilterChainImpl filterChain = new FilterChainImpl(this); return filterChain.dataSource_connect(this, maxWaitMillis); } else {// If filter does not exist, get the connection directly. return getConnectionDirect(maxWaitMillis); }}Copy the code

Finally, the connection method is obtained:

poolableConnection = getConnectionInternal(maxWaitMillis);
Copy the code

In this method, also generated from DruidConnectionHolder:

 DruidPooledConnection poolalbeConnection = new DruidPooledConnection(holder);
 return poolalbeConnection;
Copy the code

Look at the constructor:

   public DruidPooledConnection(DruidConnectionHolder holder){
        super(holder.getConnection());

        this.conn = holder.getConnection();
        this.holder = holder;
        this.lock = holder.lock;
        dupCloseLogEnable = holder.getDataSource().isDupCloseLogEnable();
        ownerThread = Thread.currentThread();
        connectedTimeMillis = System.currentTimeMillis();
    }

Copy the code

DruidPooledConnection actually holds a DruidConnectionHolder internally. The DruidPooledConnection data structure is as follows:

name type instructions
conn Connection Point to a real database connection.
holder volatile DruidConnectionHolder Pointing to the DruidConnectionHolder.
transactionInfo TransactionInfo Transaction-related information

The relationship between these key classes is shown below:

Personally, DruidConnectionHolder and DruidPooledConnection actually layer connections. Abstracts frequently changing content into the DruidConnectionHolder class. DruidPooledConnection stores the Statement’s cache pool.