【发布时间】:2015-04-07 08:31:22
【问题描述】:
我有一个通过 Qt QSqlDatabase 接口连接到 Oracle 数据库的 C++ 应用程序。主应用程序建立并使用与数据库的连接,同时为不相关的其他 porpuses 启动子进程。明确一点:子进程不使用任何与数据库相关的东西。
现在的问题是:如果主进程以不寻常的方式终止(它崩溃或被用户通过任务管理器杀死),我可以看到 Oracle 服务器上的数据库会话保持活动状态并且确实无论如何都不会超时。绝对可重现,但是,在我手动终止子进程后,会话立即被取消。
由于那些悬空的孤立会话会导致一些问题(最简单的蜂鸣器达到服务器上的最大会话数),我真的希望尽快关闭所有会话。
我现在的问题是:仅仅因为不相关的子进程仍然存在而使服务器上的会话保持活跃的机制是什么?我如何控制这种行为,即告诉 oracle 客户端在主应用程序进程死亡时断开任何会话?
提前致谢!
【问题讨论】:
-
子进程可以继承操作系统句柄。使用 Process Explorer 到inspect the file handles,查看是否有与 Oracle Server 相关的。发布生成子进程的代码,并验证 bInheritHandles 是否为 FALSE。
-
PS:有一种方法可以从 OCI 库中获取文件(套接字)句柄,但它需要大量的黑魔法。
-
@sashoalm:感谢您的提示,但不幸的是,这似乎不是原因。我通过QProcess 启动子进程。我刚刚步入Qt源码,QProcess以bInheritHandles == false (
{ sizeof(SECURITY_ATTRIBUTES), 0, false })开始进程 -
如果杀死子进程释放会话,它仍然必须是关于它的。你检查过孩子的把手吗?有什么可疑之处吗?会话连接的本质是什么 - 它是套接字还是其他东西?
-
在你 fork 一个新进程之前和之后简单地比较 netstat 在双方(客户端和服务器)的输出。文件句柄要么是从父级继承的,要么与 QSqlDatabase 健康检查(如果有)有关。