/**
* retrieve all table names of databases
* @param projPath
* @param maxThread max number of thread
* @return
*/
public static List<DBInfo> retreiveAllTables(String projPath, int maxThread) {
ExecutorService threadPool = Executors.newCachedThreadPool();
final ConcurrentLinkedQueue<DBInfo> queue = new ConcurrentLinkedQueue<DBInfo>();
ArrayList<DBInfo> dbInfos = null;
try { dbInfos = new ArrayList<DBInfo>(getDBInfos(projPath)); //get all the dbinfo of the project without table name information Collections.sort(dbInfos, new Comparator<DBInfo>() {
public int compare(DBInfo o1, DBInfo o2) {
return o1.getType().compareTo(o2.getType());
}
}); ListUtil.putToQueue(dbInfos, queue);//put list's elements into a queue
} catch (ConfigurationException e) {
log.error(e, e);
} ArrayList<Callable<Object>> threads = new ArrayList<Callable<Object>>();
for (int i = 0; i < maxThread; i++) {
threads.add(new Callable<Object>() {
public Object call() throws Exception {
while (true) {
DBInfo dbInfo = queue.poll();
if (dbInfo == null) {
return null;
} else {
log.debug("thread fetching table: "+Thread.currentThread().getName()+", "+dbInfo.getName());
retreiveTables(dbInfo); //retreive all table names from the database of the dbinfo
}
}
}
});
} try {
threadPool.invokeAll(threads);
threadPool.shutdown();
} catch (InterruptedException e) {
log.error(e, e);
} return dbInfos;
} public static void retreiveTables(DBInfo dbInfo) throws SQLException {
Connection tempConn = null;
try {
tempConn = ConnFactory.getConnection(dbInfo.getType(), dbInfo.getConnUrl(),
dbInfo.getUserName(), dbInfo.getPassword());
} catch (ClassNotFoundException e) {
log.error(e, e);
} catch (IllegalAccessException e) {
log.error(e, e);
} catch (InstantiationException e) {
log.error(e, e);
}
retreiveTables(tempConn.getMetaData(), dbInfo);
}
public static void retreiveTables(DatabaseMetaData dmd, DBInfo dbInfo) throws SQLException {
String[] types = {"TABLE"};
ResultSet resultSet = null; if (dbInfo.getType().equals("oracle") || dbInfo.getType().equals("mysql")) {
resultSet = dmd.getTables(null, dbInfo.getUserName().toUpperCase(), "%", types);
} else {
resultSet = dmd.getTables(null, null, "%", types);
}
// Get the table names
while (resultSet.next()) {
// Get the table name
String tableName = resultSet.getString(3); // Get the table's catalog and schema names (if any)
String tableCatalog = resultSet.getString(1);
String tableSchema = resultSet.getString(2);
// log.debug(String.format("catalog : %s, schema : %s",tableCatalog,tableSchema));
dbInfo.addTable(tableName);
} Collections.sort(dbInfo.getTables(), new Comparator<String>() {
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
}
我调用retreiveAllTables(String projPath, int maxThread)方法来检索当前工程所有数据库的所有表,工程中有262个数据库,有的库表达到1000多个表,有oracle,mysql,ms sqlserver三种数据库,现在的问题是,如果传递的;maxthread为5的话,只检索了8、9个库之后,线程就退出了,并没有继续执行,如果我传递大于262的值比如300,则所有的线程都执行完才退出。真是百思不得其解。
if (dbInfo == null) {
return null;
} else {
log.debug("thread fetching table: "+Thread.currentThread().getName()+", "+dbInfo.getName());
retreiveTables(dbInfo); //retreive all table names from the database of the dbinfo
}
你确定dbInfo 不会为null吗?
另外考虑把:
public Object call()
函数中直接套上个大的try{}catch(Exceptio ex),记得输出异常。
另外在:
DBInfo dbInfo = queue.poll();
后面直接增加一句:
System.out.println(dbInfo);看看poll了多少次内容,是否跟queue的大小一致。
嗯,确实是出异常了,try罩在call的整个方法体后,出现了java.sql.SQLException: The XAEMULATION connection property is invalid的异常,当线程数设得比较小,如3时会出现,是jtds的sql server驱动抛出的,如果设得比较大,则不会有问题
目前用的jtds是最新的1.2.5,过段时间有时间了,再试试微软的驱动。