diff --git a/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceSelector.java b/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceSelector.java index e8f5b9fddd..693b3351c5 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceSelector.java +++ b/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceSelector.java @@ -86,21 +86,10 @@ public class RandomDataSourceSelector implements DataSourceSelector { return null; } - Collection targetDataSourceSet; - if (blacklist == null || blacklist.isEmpty() || blacklist.size() >= dataSourceMap.size()) { - targetDataSourceSet = dataSourceMap.values(); - } else { - targetDataSourceSet = new HashSet(dataSourceMap.values()); - for (DataSource b : blacklist) { - targetDataSourceSet.remove(b); - } - } - - DataSource[] dataSources = targetDataSourceSet.toArray(new DataSource[] {}); - if (dataSources != null && dataSources.length > 0) { - return dataSources[random.nextInt(targetDataSourceSet.size())]; - } - return null; + Collection targetDataSourceSet = removeBlackList(dataSourceMap); + removeBusyDataSource(targetDataSourceSet); + DataSource dataSource = getRandomDataSource(targetDataSourceSet); + return dataSource; } @Override @@ -182,6 +171,41 @@ public class RandomDataSourceSelector implements DataSourceSelector { new Thread(recoverThread, "RandomDataSourceSelector-recover-thread").start(); } + private Collection removeBlackList(Map dataSourceMap) { + Collection dataSourceSet; + if (blacklist == null || blacklist.isEmpty() || blacklist.size() >= dataSourceMap.size()) { + dataSourceSet = dataSourceMap.values(); + } else { + dataSourceSet = new HashSet(dataSourceMap.values()); + for (DataSource b : blacklist) { + dataSourceSet.remove(b); + } + } + return dataSourceSet; + } + + private void removeBusyDataSource(Collection dataSourceSet) { + Collection busyDataSourceSet = new HashSet(); + for (DataSource ds : dataSourceSet) { + if (ds instanceof DruidDataSource && ((DruidDataSource) ds).getPoolingCount() <= 0) { + busyDataSourceSet.add(ds); + } + } + if (!busyDataSourceSet.isEmpty() && busyDataSourceSet.size() < dataSourceSet.size()) { + for (DataSource ds : busyDataSourceSet) { + dataSourceSet.remove(ds); + } + } + } + + private DataSource getRandomDataSource(Collection dataSourceSet) { + DataSource[] dataSources = dataSourceSet.toArray(new DataSource[] {}); + if (dataSources != null && dataSources.length > 0) { + return dataSources[random.nextInt(dataSourceSet.size())]; + } + return null; + } + public HighAvailableDataSource getHighAvailableDataSource() { return highAvailableDataSource; } diff --git a/src/main/java/com/alibaba/druid/pool/ha/selector/StickyRandomDataSourceSelector.java b/src/main/java/com/alibaba/druid/pool/ha/selector/StickyRandomDataSourceSelector.java index a06b8de271..869a4b1404 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/selector/StickyRandomDataSourceSelector.java +++ b/src/main/java/com/alibaba/druid/pool/ha/selector/StickyRandomDataSourceSelector.java @@ -48,7 +48,7 @@ public class StickyRandomDataSourceSelector extends RandomDataSourceSelector { @Override public DataSource get() { StickyDataSourceHolder holder = holders.get(); - if (holder != null && isValid(holder) && !isExpired(holder)) { + if (holder != null && isAvailable(holder)) { LOG.debug("Return the sticky DataSource " + holder.getDataSource().toString() + " directly."); return holder.getDataSource(); } @@ -60,6 +60,14 @@ public class StickyRandomDataSourceSelector extends RandomDataSourceSelector { return dataSource; } + private boolean isAvailable(StickyDataSourceHolder holder) { + boolean flag = isValid(holder) && !isExpired(holder); + if (flag && holder.getDataSource() instanceof DruidDataSource) { + flag = ((DruidDataSource) holder.getDataSource()).getPoolingCount() > 0; + } + return flag; + } + private boolean isValid(StickyDataSourceHolder holder) { boolean flag = holder.isValid() && !getBlacklist().contains(holder.getDataSource()); if (!(holder.getDataSource() instanceof DruidDataSource) || !flag) {