我的要求與this很相似,只不過我長時間運行的IO操作是數據庫選擇。中斷執行長時間運行的數據庫選擇的線程
在該線程中提出了一個相當有創意的解決方案,涉及在單獨的線程中關閉IO流。但是,我並沒有真正引用輸入流或套接字。
我甚至無法關閉正在使用的連接,因爲我使用了spring-jdbc,該連接不允許我訪問正在使用的基礎連接。我相信JdbcTemplate.getDataSource().getConnection()
可能會從數據源返回另一個連接。
感謝任何幫助/建議,我可以得到。
我的要求與this很相似,只不過我長時間運行的IO操作是數據庫選擇。中斷執行長時間運行的數據庫選擇的線程
在該線程中提出了一個相當有創意的解決方案,涉及在單獨的線程中關閉IO流。但是,我並沒有真正引用輸入流或套接字。
我甚至無法關閉正在使用的連接,因爲我使用了spring-jdbc,該連接不允許我訪問正在使用的基礎連接。我相信JdbcTemplate.getDataSource().getConnection()
可能會從數據源返回另一個連接。
感謝任何幫助/建議,我可以得到。
使用JdbcTemplate.execute(PreparedStatementCreator, PreparedStatementCallback)
在PreparedStatementCreator,您可以訪問的聲明,你可以給另一個線程。這個其他線程創建一個計時器並在必要時在Statement上調用.cancel。
正如Istvan所提到的,PreparedStatementCreator是要走的路。 粘貼我的實施,以防其有用..
private final long timeout = 1000; //timeout in seconds
final SqlRowSet rowSet = jdbcTemplate.getJdbcOperations().query(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
if (timeout>0){
Timer timer = new Timer();
timer.schedule(new ConnectionInterrupter(con), timeout*1000);
}
return con.prepareStatement(queryString);
}
}, new ResultSetExtractor<SqlRowSet>() {
@Override
public SqlRowSet extractData(ResultSet rs) throws SQLException, DataAccessException {
CachedRowSet rowSet = newCachedRowSet();
rowSet.populate(rs);
return new ResultSetWrappingSqlRowSet(rowSet);
}
protected CachedRowSet newCachedRowSet() throws SQLException {
return new CachedRowSetImpl();
}
});
private class ConnectionInterrupter extends TimerTask {
private final Connection connection;
public ConnectionInterrupter(Connection connection) {
this.connection = connection;
}
@Override
public void run() {
try {
logger.warn("Connection timeout has occurred. Manually closing the connection ...");
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}