【发布时间】:2014-12-10 21:06:19
【问题描述】:
我有以下 Callable 实例,这里抛出了 SQLException:
public long[] call() throws Exception {
long[] stats = new long[6];
try {
executer.acquire();
PreparedStatement statement =
connection
.prepareStatement("SELECT `War`.`EndTime` FROM `WarSim`.`War` WHERE `War`.`WarName` = ?");
statement.setString(1, warName);
ResultSet res = statement.executeQuery(); //<--------------SQLEXCEPTION HERE
if (res.first()) {
Timestamp ts = res.getTimestamp("EndTime");
if (ts != null)
stats[0] = 1;
statement =
connection
.prepareStatement("SELECT COUNT(`ID`) FROM `Missile` WHERE `WarName` = ?");
statement.setString(1, warName);
res = statement.executeQuery();
stats[1] = res.getInt(1);
statement =
connection
.prepareStatement("SELECT COUNT(`ID`) FROM `Missile` WHERE `WarName` = ? AND `Intercepted` = '1'");
statement.setString(1, warName);
res = statement.executeQuery();
stats[2] = res.getInt(1);
stats[3] = stats[1] - stats[2];
statement =
connection
.prepareStatement("SELECT COUNT(`ID`) FROM `EnemyLauncher` WHERE `WarName` = ? AND `Intercepted` = '1'");
statement.setString(1, warName);
res = statement.executeQuery();
stats[4] = res.getInt(1);
statement =
connection
.prepareStatement("SELECT SUM(`Damage`) FROM `Missile` WHERE `WarName` = ? AND `Intercepted` = '0'");
statement.setString(1, warName);
res = statement.executeQuery();
stats[5] = res.getInt(1);
}
} catch (SQLException e) {
System.out.println(warName + " is problematic");
while (e != null) {
System.out.println("\tmsg: " + e.getMessage()+
"\n\tstate: " + e.getSQLState());
e = e.getNextException();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
executer.release();
}
return stats;
}
executer 是我使用的单一许可、公平信号量。
当我调试代码时,一切正常(没有例外),但是当我“正常”运行程序时,我得到了“结果集开始”SQLException 以及 SQLState S1000。
即使我使用信号量获取要查询的互斥体,我怎么会出现异常?
请帮忙:)
编辑:这是堆栈跟踪。
java.sql.SQLException: Before start of result set
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929)
at com.mysql.jdbc.ResultSetImpl.checkRowPos(ResultSetImpl.java:841)
at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2672)
at db.jdbc.GetWarStatsTask.call(GetWarStatsTask.java:37)
at db.jdbc.GetWarStatsTask.call(GetWarStatsTask.java:1)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
处理数据库连接的类:
public class JDBCConnection implements DBConnection {
private Connection connection;
private String dbUrl;
private Semaphore executer;
private ExecutorService es;
private static JDBCConnection instance;
public static JDBCConnection getInstance() {
if (instance == null) {
instance = new JDBCConnection();
}
return instance;
}
private JDBCConnection() {
dbUrl = "jdbc:mysql://---------/WarSim";
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection =
DriverManager.getConnection(dbUrl, "------", "-------");
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
while (e != null) {
System.out.println(e.getMessage());
e = e.getNextException();
}
}
es = Executors.newCachedThreadPool();
executer = new Semaphore(1, true);
}
public Future<long[]> getWarStats(String warName) {
return es.submit(new GetWarStatsTask(executer, connection, warName));
}
public void closeDB() {
try {
if (connection != null) {
connection.close();
}
} catch (Exception e) {
System.out.println("Could not close the current connection.");
e.printStackTrace();
}
}
【问题讨论】:
-
你能发布堆栈跟踪的前几行吗?
-
添加到问题正文谢谢。
-
您的结果集何时关闭,连接何时关闭?也许这是内存泄漏的症状。
-
在你的问题中你说:
"When I debug the code, everything works perfectly (no exceptions), yet when I run the program "normally" I get the "start of result set" SQLException thrown along with SQLState S1000."当你“正常”运行它时你有什么不同。你如何产生线程并清理它们? -
线程是通过 Executor 产生的。我会添加信息
标签: java mysql multithreading jdbc