我有一个报告窗口,显示从可能长时间运行的oracle存储过程返回的结果。我的问题是当用户关闭窗口时,与oracle的连接仍然打开,并且可能长时间运行的报告不会被取消。
关闭开放连接的唯一方法是让DBA手动终止它们或让用户退出整个应用程序。
我尝试从另一个线程调用Close
连接,但这似乎不断阻塞。我也试过回滚一个交易,但这也表现出同样的问题。
我担心唯一的解决方案是在不同的进程(或者可能是app域?)中运行查询。
我可能会遗漏一些明显的东西,任何帮助都会受到高度赞赏。
请仔细阅读
这个问题不是关于在using
语句中包装我的连接。它是关于如何强制执行查询的oracle连接关闭。
示例:
在连接对象上调用close
public void Go()
{
OracleConnection connection;
var queryThread = new Thread(
() =>
{
using (connection = OpenOracleConnection())
{
// execute stored proc that takes 45 mins
// raise an event with the data set we load
}
});
Thread.Sleep(3000); // give it time to be useless
var closeThread = new Thread(
() =>
{
connection.Close();
});
closeThread.Start();
}
问题是这不会关闭连接,而是调用connection.Close()来阻止等待程序执行。
答案 0 :(得分:3)
嗯,我在API中看不到任何中止/取消正在进行的查询的内容。从技术上讲,第二个具有完全权限的会话应该可以识别要中止的会话,并在该会话上发出kill session命令。我希望你的原始会话可以通过某种例外来拯救,但我从来没有尝试过。
Here解释了如何终止会话。
Here回答了如何获取会话ID。您可以在开始长时间运行查询之前找到一个,然后从第二个连接中删除该会话应该非常容易。
让我们知道它是否有效;)
答案 1 :(得分:1)
要查看阻止谁的人/谁:
select s1.username || '@' || s1.machine
|| ' ( SID=' || s1.sid || ' ) is blocking '
|| s2.username || '@' || s2.machine || ' ( SID=' || s2.sid || ' ) ' AS status
from v$lock l1, v$session s1, v$lock l2, v$session s2
where s1.sid=l1.sid and s2.sid=l2.sid
and l1.BLOCK=1 and l2.request > 0
and l1.id1 = l2.id1
and l2.id2 = l2.id2;
答案 2 :(得分:0)
与.NET中的任何提供程序一样,您可以调用Dispose
using(var conn = /* your connection */) {
// do your stuff
conn.Close();
} // this will automatically call .Dispose()
这就是你需要做的一切。