当关闭连接池需要太多时间时,如何强制关闭连接池中的连接?

有时关闭连接需要花费大量时间,例如超过10分钟到1小时,或者更糟,即使是无限期,取决于查询的重量或速度。

在客户端因为花费太多时间而取消查询的情况下,我希望尽快释放使用的底层连接。

我尝试取消PreparedStatement,关闭它,然后关闭结果集,然后最后关闭连接。 几乎立即取消。 关闭PreparedStatement和ResultSet需要花费太多时间,我必须将它包装在Callable with timeout中,以便在适当的时候跳过该进程并继续关闭连接本身。 我还没有什么运气可以试试。

我该如何处理? 我不能简单地让连接不公开,我不能让用户等待10分钟才能进行另一个类似的查询。

是什么原因导致连接关闭需要花费太多时间? 还有什么我能做的吗? 您认为Oracle查询提示会有帮助吗?

顺便说一下,我正在通过瘦型驱动程序使用Oracle JDBC。

更新:

显然,可以通过在connectionCacheProperties中配置TimeToLive属性来强制关闭连接,该属性会在特定时间内关闭连接。 但是,我需要的是根据需要。 这值得一提,因为这certificate可以像连接池那样强制关闭它。 事实上,我甚至在我的日志上收到以下消息。

ORA-01013: user requested cancel.. 

主function:

  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 // 

这是我们在POW中使用的,而不是“将alter system添加到$ 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; / 

这样你只能杀死你自己的会话。