如何修复此 Try-With-Resources 块中的 "SQLServerException: The connection is closed." 事件?
How to fix the "SQLServerException: The connection is closed." occurrence in this Try-With-Resources block?
我正在对 DBMS 进行性能测试。我必须为我的硕士论文手动完成。我必须有一定数量的线程,每个线程都打开自己的 JDBC 连接到数据库(连接池不是一个选项)并提交相同数量的相同事务(每个线程做相同的工作) .我在 try-with-resources
块中将连接作为资源打开。连接应保持打开状态直到 try-with-resources
范围结束,但有时会打开,有时不会。
try (Connection conn = getConn();
PreparedStatement simpleSelectStmt = conn
.prepareStatement(tcInstance.getQueryMap().get("SimpleSelect").getSimpleSelect())) {
setConnIsolation(conn);
long startTime = System.nanoTime();
singleThread.execute(new Runnable() {
@Override
public void run() {
for (int j = 0; j < tcInstance.getnT(); j++) {
try {
conn.setAutoCommit(false);
simpleSelectStmt.execute();
conn.commit();
} catch (Exception e) {
error++;
if (detectDeadlock(e.getMessage())) {
deadlock++;
System.out.println("Deadlock detected!");
} else {
e.printStackTrace();
}
try {
if (conn != null) {
conn.rollback();
}
} catch (SQLException e1) {
System.out.println("There was an error in rolling back the transaction.");
e1.printStackTrace();
}
}
if (j != (tcInstance.getnT() - 1)) {
try {
Thread.sleep(t);// ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
measureCPUusage(Thread.currentThread().getId());
singleThread.shutdown();
});
long endTime = System.nanoTime();
....doing some other measurements....
} catch (Exception e) {
System.err.println("Error");
}
这是用于获取 jdbc 连接的 getConn()
方法:
private Connection getConn() throws SQLException {
return DriverManager.getConnection(tcInstance.getJDBCurl(), tcInstance.getUser(), tcInstance.getPassword());
}
我希望通过整个 try-with-resources 块打开连接,但是 conn.setAutoCommit(false);
和 conn.rollback();
行出现连接已关闭异常
请为每个线程打开单独的连接。您为一个线程打开的连接被另一个线程关闭,因此您得到 exception.Also,请提供有关 detectDeadlock 的更多信息以进一步帮助您。我希望你在多线程环境中的简单连接不需要这样的东西。
简而言之,您的代码流程似乎是这样的:
try (Connection conn = getConn()) {
setConnIsolation(conn);
// Posted from Thread-1
singleThread.execute(new Runnable() {
@Override
public void run() {
// Thread-2 accesses conn created on Thread-1
// use conn here..
});
// ....doing some other work....
} catch (Exception e) {
System.err.println("Error");
}
//Conn is released
当runnable 开始工作时,其对应的线程可能正在使用已释放的conn。这是因为,发布线程在发布 runnable 之后,从 Try-With-Resources 块中出来,作为其中的一部分,Conn 被释放。
解决方法:
将 Conn 带出 Try-With-Resources 街区。
我正在对 DBMS 进行性能测试。我必须为我的硕士论文手动完成。我必须有一定数量的线程,每个线程都打开自己的 JDBC 连接到数据库(连接池不是一个选项)并提交相同数量的相同事务(每个线程做相同的工作) .我在 try-with-resources
块中将连接作为资源打开。连接应保持打开状态直到 try-with-resources
范围结束,但有时会打开,有时不会。
try (Connection conn = getConn();
PreparedStatement simpleSelectStmt = conn
.prepareStatement(tcInstance.getQueryMap().get("SimpleSelect").getSimpleSelect())) {
setConnIsolation(conn);
long startTime = System.nanoTime();
singleThread.execute(new Runnable() {
@Override
public void run() {
for (int j = 0; j < tcInstance.getnT(); j++) {
try {
conn.setAutoCommit(false);
simpleSelectStmt.execute();
conn.commit();
} catch (Exception e) {
error++;
if (detectDeadlock(e.getMessage())) {
deadlock++;
System.out.println("Deadlock detected!");
} else {
e.printStackTrace();
}
try {
if (conn != null) {
conn.rollback();
}
} catch (SQLException e1) {
System.out.println("There was an error in rolling back the transaction.");
e1.printStackTrace();
}
}
if (j != (tcInstance.getnT() - 1)) {
try {
Thread.sleep(t);// ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
measureCPUusage(Thread.currentThread().getId());
singleThread.shutdown();
});
long endTime = System.nanoTime();
....doing some other measurements....
} catch (Exception e) {
System.err.println("Error");
}
这是用于获取 jdbc 连接的 getConn()
方法:
private Connection getConn() throws SQLException {
return DriverManager.getConnection(tcInstance.getJDBCurl(), tcInstance.getUser(), tcInstance.getPassword());
}
我希望通过整个 try-with-resources 块打开连接,但是 conn.setAutoCommit(false);
和 conn.rollback();
请为每个线程打开单独的连接。您为一个线程打开的连接被另一个线程关闭,因此您得到 exception.Also,请提供有关 detectDeadlock 的更多信息以进一步帮助您。我希望你在多线程环境中的简单连接不需要这样的东西。
简而言之,您的代码流程似乎是这样的:
try (Connection conn = getConn()) {
setConnIsolation(conn);
// Posted from Thread-1
singleThread.execute(new Runnable() {
@Override
public void run() {
// Thread-2 accesses conn created on Thread-1
// use conn here..
});
// ....doing some other work....
} catch (Exception e) {
System.err.println("Error");
}
//Conn is released
当runnable 开始工作时,其对应的线程可能正在使用已释放的conn。这是因为,发布线程在发布 runnable 之后,从 Try-With-Resources 块中出来,作为其中的一部分,Conn 被释放。
解决方法: 将 Conn 带出 Try-With-Resources 街区。