有时关闭连接需要花费大量时间,例如超过10分钟到1小时,或者更糟,甚至是无限期,具体取决于查询的重度或速度。
在客户端取消查询的情况下,因为它花费了太多时间,我想尽快释放使用的基础连接。
我尝试取消PreparedStatement,关闭它,然后关闭结果集,然后最后关闭连接。几乎立即取消。关闭PreparedStatement和ResultSet需要花费太多时间,我必须将它包装在具有超时的Callable中,以便在适当的时候跳过该进程并继续关闭连接本身。我还没有什么运气可以尝试。
我该如何处理?我不能简单地让连接不公开,我不能让用户等待10分钟才能进行另一次类似的查询。
另外,导致连接关闭的原因是花费太多时间?还有什么我能做的吗?您认为Oracle查询提示会有帮助吗?
顺便说一句,我正在通过瘦型驱动程序使用Oracle JDBC。
更新:
显然,可以通过在connectionCacheProperties中配置TimeToLive属性来强制关闭连接,该属性会在特定时间内关闭连接。但是,我需要的是根据需要。这值得一提,因为这证明可以像连接池那样强制关闭它。事实上,我甚至在日志中收到以下消息。
ORA-01013: user requested cancel..
答案 0 :(得分:1)
主要功能:
String g_sid = "";
主题1:
String sql = ...;
Connection conn = ...your connection func...;
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery( "SELECT sid from v$mystat");
if (rset.next()) g_sid = rset.getString("sid");
rset.close();
// now to the actual long-running SQL
ResultSet rset = stmt.executeQuery( sql );
//
stmt.close();
主题2:
String serialN = "";
Connection conn = ...your admin connection func...
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery( "SELECT serial# serialN from v$session where sid=" + g_sid );
if (rset.next()) {
serialN = rset.getString("serialN");
stmt.execute("alter system kill session '" + g_sid + "," + serialN + "'");
}
stmt.close();
// probably keep the admin connection open for further maintenance
//
答案 1 :(得分:1)
这是我们在POW中使用的,而不是“将更改系统授予$ UID”作为SYS拥有的程序(简化工作版本):
CREATE OR REPLACE procedure SYS.kill_session(in_sid varchar2)
as
l_serial number;
l_runsql varchar2(1000) := 'alter system kill session ''$1,$2'' immediate';
begin
begin
select serial# into l_serial from v$session where username =
(
SELECT USER FROM DUAL
) and sid=in_sid and rownum<=1;
exception when no_data_found then
raise_application_error( -20001, 'Kill candidate not found');
end;
l_runsql := replace( l_runsql, '$1', in_sid);
l_runsql := replace( l_runsql, '$2', l_serial);
execute immediate l_runsql;
end;
/
这样你只能杀死自己的会话。