C# 在C中强制关闭oracle连接#
我有一个报告窗口,显示从可能长期运行的oracle存储过程返回的结果。我的问题是,当用户关闭窗口时,与oracle的连接保持打开状态,并且潜在的长时间运行报告不会被取消 关闭打开的连接的唯一方法是让DBA手动终止连接,或者让用户退出整个应用程序 我尝试从另一个线程对连接调用C# 在C中强制关闭oracle连接#,c#,oracle,C#,Oracle,我有一个报告窗口,显示从可能长期运行的oracle存储过程返回的结果。我的问题是,当用户关闭窗口时,与oracle的连接保持打开状态,并且潜在的长时间运行报告不会被取消 关闭打开的连接的唯一方法是让DBA手动终止连接,或者让用户退出整个应用程序 我尝试从另一个线程对连接调用Close,但这似乎会持续阻塞。我还尝试回滚一个事务,但这显示出同样的问题 我担心唯一的解决方案是在另一个进程(或者可能是应用程序域?)中运行查询 很可能我遗漏了一些明显的东西,任何帮助都将不胜感激 请阅读 这个问题不是关于使
Close
,但这似乎会持续阻塞。我还尝试回滚一个事务,但这显示出同样的问题
我担心唯一的解决方案是在另一个进程(或者可能是应用程序域?)中运行查询
很可能我遗漏了一些明显的东西,任何帮助都将不胜感激
请阅读
这个问题不是关于使用语句将我的连接包装在中。它是关于如何强制执行查询的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()的调用会阻止等待过程执行。与.NET中的任何提供程序一样,您可以调用Dispose
using(var conn = /* your connection */) {
// do your stuff
conn.Close();
} // this will automatically call .Dispose()
这就是您所需要做的。Hm,我在API中看不到任何中止/取消正在进行的查询的内容。从技术上讲,应该可以使用第二个具有完全权限的会话来识别要中止的会话,并在该会话上发出kill session命令。我希望你最初的治疗会有例外,但我从未尝试过
它解释了如何终止会话
它回答了如何获取会话id。在启动长时间运行的查询之前,您可以找到一个会话id,然后从第二个连接中完全终止该会话应该非常容易
让我们知道它是否有效;) 要查看是什么/谁阻止了谁:
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;
当打开连接且当前正在执行查询的线程被阻塞45分钟时,我如何调用close或dispose?我必须承认,我对Oracle数据库的经验有限,但我可以告诉您,查询被阻塞45分钟是不正常的。如果您公布了如何打开连接,您应该能够关闭连接,但您不能表示这是您的代码。并非所有查询都需要45分钟,大多数查询在几秒钟内执行,但这需要人们提供参数以减少结果集,不幸的是,它们并不总是提供正确的查询。哦,要清楚,如果您在TOAD中手动运行相同的查询,也需要45分钟,这进一步表明这与现有代码无关。您使用的是哪个ADO.NET Oracle提供程序?(Microsoft提供的不支持异步处理,因此如果是异步处理,您可能需要编写代码以在另一个连接中进行连接并终止违规进程)。11.2.0附带的Oracle.DataAccess提供程序不是一个好问题。显然,您必须先中止查询。除非你解释一下你是如何启动这起火车事故的,否则你不会得到答案,“报告窗口”毫无意义。邮政编码。感谢您的有用反馈。虽然发布我的代码会很有用,但它会使任何看过它的人失明。我从另一个线程运行oracle过程是偶然的,但我将尝试演示我的代码。@Hans Passant,显然我必须中止查询。显然,我该如何中止查询?好主意,我会在DBA面前运行它,看看他们是否愿意这样做。我认为这意味着赋予调用凭据更改系统的能力,这可能无法运行。您可以使用不同的用户来执行终止会话,而不必是同一个帐户……我已经完成了这项工作,效果很好,这为我指明了正确的方向。我正在从v$session中选择sid,serial,其中audsid=sys\u context('userenv','sessionid')
然后是一个alter-system kill session(sid,session)immediate
,如果用户需要中止查询。我在0.1%的情况下运行ORA-00028。我在IIS上运行数千个查询,每天有几次出现此ORA-00028:您的会话已被终止