乐趣区

关于java:连接池-Druid-补充-removeAbandoned

removeAbandoned 参数指定连接池是否移除被遗弃的连贯。

具体的逻辑分两局部:一部分是设置流动连贯、筹备未来判断是否应该被遗弃,这个动作是在 getConnection 获取连贯后执行的;另外一部分是在连贯回收工作 DestroyTask 中,咱们在剖析连贯回收的文章中疏忽了这部分内容,明天补充一下。

getConnection 办法获取连贯之后判断 removeAbandoned 参数关上的话,就设置以后连贯的 connectedTimeNano 为零碎工夫,而后将以后连贯放入 activeConnections 中,筹备被回收线程查看、移除。

代码在 getConnectionDirect 中:

           if (removeAbandoned) {StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
                poolableConnection.connectStackTrace = stackTrace;
                poolableConnection.setConnectedTimeNano();
                poolableConnection.traceEnable = true;

                activeConnectionLock.lock();
                try {activeConnections.put(poolableConnection, PRESENT);
                } finally {activeConnectionLock.unlock();
                }
            }

第二局部须要回顾一下上一篇文章中的 DestroyTask 的 run 办法,在调用 shrink 之后判断 RemoveAbandoned 则调用 removeAbandoned() 办法:


        @Override
        public void run() {shrink(true, keepAlive);

            if (isRemoveAbandoned()) {removeAbandoned();
            }
        }

removeAbandoned 办法源码,分段贴出:

   public int removeAbandoned() {
        int removeCount = 0;

        long currrentNanos = System.nanoTime();

        List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();

        activeConnectionLock.lock();
        try {Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();

            for (; iter.hasNext();) {DruidPooledConnection pooledConnection = iter.next();

                if (pooledConnection.isRunning()) {continue;}

                long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000);

                if (timeMillis >= removeAbandonedTimeoutMillis) {iter.remove();
                    pooledConnection.setTraceEnable(false);
                    abandonedList.add(pooledConnection);
                }
            }
        } finally {activeConnectionLock.unlock();
        }

首先 activeConnectionLock 加锁。

循环查看 activeConnections 中的每一个连贯。

如果连贯 isRunning() 的话,则不解决以后连贯。连贯的 running 状态是在连贯执行 sql 语句前调用 beforeExecute 办法设置为 true、执行实现后调用 afterExecute 办法设置为 false 的。也就是说 running 状态其实就是字面意思,如果一个连贯正在执行 sql 语句,running 为 true,执行实现后,running 为 false。

计算 timeMillis 为连贯获取之后到当初的时长,留神 connectedTimeNano 是在咱们下面所说的第一步:连贯获取之后设置的。

如果 timeMillis 大于参数设定的移除时长 removeAbandonedTimeoutMillis 的话,则连贯放入 abandonedList 中筹备移除。

之后,开释 activeConnectionLock 锁。

前面的代码就不贴出了,很简略,就是从 abandonedList 列表中一一取出连贯,敞开连贯,标记以后连贯的 abandoned=true。

总结

联合 Druid 连接池的连贯偿还过程,总结一下 removeAbandoned 参数的总体应用逻辑:

  1. removeAbandoned 参数设置为 true 的话,须要配合设置一个 removeAbandonedTimeoutMillis,认定连贯被遗弃的时长
  2. 从连贯给获取到开始计时,并将连贯放入到流动连贯 activeConnections 中
  3. 连贯在执行 sql 语句过程中(running 状态)不会被认定为遗弃而回收
  4. 连贯执行实现、偿还到连接池的时候,如果还没有被认定为遗弃,则从 activeConnections 中移除(平安了 …)
  5. 连贯尚未归还给连接池、也不在 running 状态的状况下(比方利用在执行完 sql 语句之后不 close 连贯的状况下),连贯回收线程查看该连贯自从被 getConnection 获取之后到当初的时长如果大于 removeAbandonedTimeoutMillis 的话,就会给该连贯打标记:须要被遗弃。并敞开该连贯,不再容许其偿还到连接池

无关 removeAbandoned 参数,在初始化过程中的 initCheck() 办法中有一段代码:

         if (removeAbandoned) {LOG.warn("removeAbandoned is true, not use in production.");
        }

意思很明确,removeAbandoned 参数并不是用在生产环境中的,是专为测试环境筹备的参数。 因而,倡议大家开发过程中罗唆遗记这个参数,不要设置为关上。

上一篇 连接池 Druid(四)– 连贯偿还

退出移动版