今天没有使用mybatis连接数据,而是直接创建的DruidDataSource连接的数据,程序启动时,一直卡着启动不了;调试后发现, 是DruidDataSource.getConnection时卡住了。跟着代码走进去,发现卡在了takeLast这个函数上面,该函数代码如下:
DruidConnectionHolder takeLast() throws InterruptedException, SQLException {
try {
while (poolingCount == 0) {
emptySignal(); // send signal to CreateThread create connection
if (failFast && isFailContinuous()) {
throw new DataSourceNotAvailableException(createError);
}
notEmptyWaitThreadCount++;
if (notEmptyWaitThreadCount > notEmptyWaitThreadPeak) {
notEmptyWaitThreadPeak = notEmptyWaitThreadCount;
}
try {
notEmpty.await(); // signal by recycle or creator
} finally {
notEmptyWaitThreadCount--;
}
notEmptyWaitCount++;
if (!enable) {
connectErrorCountUpdater.incrementAndGet(this);
if (disableException != null) {
throw disableException;
}
throw new DataSourceDisableException();
}
}
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to non-interrupted thread
notEmptySignalCount++;
throw ie;
}
decrementPoolingCount();
DruidConnectionHolder last = connections[poolingCount];
connections[poolingCount] = null;
return last;
}
程序卡在了 notEmpty.await(); 这儿;这儿应该是在等待线程沲的创建;一直阻塞。
查看创建参数发现,我把druid.initialSize设置为0了,这样导致创建连接时,不会初始化线程沲;
将该参数调整为1后,解决了该问题;initialSize 的默认值 DEFAULT_INITIAL_SIZE = 0;
如下代码是进入takeLast的位置 ,其中maxWait参数也很重要:
if (maxWait > 0) {
holder = pollLast(nanos);
} else {
holder = takeLast();
}
DEFAULT_MAX_WAIT = -1 没有可用连接时,最大等待时间(毫秒) ,-1:无限期等待;
所以在创建DruidDataSource时,druid.maxWait 最好设置一个值
总结:该错误需要设置两个参数:druid.initialSize=1,druid.maxWait =10*1000;