哪种机制使服务器上的Oracle会话保持活动状态? < >我有一个C++应用程序,通过Qt接口连接到Oracle数据库。主应用程序建立并使用与数据库的连接,同时为不相关的其他porpus启动子进程。要明确这一点:子进程不使用任何与数据库相关的东西

哪种机制使服务器上的Oracle会话保持活动状态? < >我有一个C++应用程序,通过Qt接口连接到Oracle数据库。主应用程序建立并使用与数据库的连接,同时为不相关的其他porpus启动子进程。要明确这一点:子进程不使用任何与数据库相关的东西,c++,oracle,qt,session,C++,Oracle,Qt,Session,现在的问题是:如果主进程以异常方式终止(它崩溃或被用户通过任务管理器杀死),我可以看到Oracle服务器上的数据库会话保持活动状态,并且不会超时。但是,在我手动终止子进程后,会话会立即取消,这是完全可以重复的 由于那些悬而未决的孤立会话会导致一些问题(最简单的问题是达到服务器上的最大会话数),我真的希望尽快关闭所有会话 我现在的问题是:什么机制可以仅仅因为一个不相关的子进程仍然处于活动状态而使会话在服务器上保持活动状态?我如何控制这种行为,即如果主应用程序进程死亡,告诉oracle客户端断开任何

现在的问题是:如果主进程以异常方式终止(它崩溃或被用户通过任务管理器杀死),我可以看到Oracle服务器上的数据库会话保持活动状态,并且不会超时。但是,在我手动终止子进程后,会话会立即取消,这是完全可以重复的

由于那些悬而未决的孤立会话会导致一些问题(最简单的问题是达到服务器上的最大会话数),我真的希望尽快关闭所有会话

我现在的问题是:什么机制可以仅仅因为一个不相关的子进程仍然处于活动状态而使会话在服务器上保持活动状态?我如何控制这种行为,即如果主应用程序进程死亡,告诉oracle客户端断开任何会话

提前谢谢

更新

在Windows上,子进程继承套接字和文件描述符,即使inheritFileDescriptors设置为false

似乎该错误已在QT5中修复


有关Oracle线程问题的讨论:

TL;博士oracle服务器不“知道”客户端已消失

一些解决方案: 1.具有终止连接检测功能:


2.如果您使用QOCI驱动程序,我的建议是尝试实现“连接池”。或者,您可以使用支持连接池的ODBC。

看起来主进程没有成功终止,在关闭数据库连接之前,在终止代码的某个位置等待子进程终止。
另一方面,子进程异常终止引发的异常情况成功传播到父进程,父进程启动终结进程并关闭与Oracle的连接


所以,第一个建议是检查子进程是否正确地对kill()和terminate()调用作出反应,即使父进程在异常终止时也会尝试终止子进程

子进程可以继承操作系统句柄。使用Process Explorer,查看是否存在与Oracle服务器相关的问题。发布生成子进程的代码,并验证其是否为FALSE。PS:有一种方法可以从OCI库获取文件(套接字)句柄,但这需要大量的黑魔法。@sashoalm:谢谢您的提示,但不幸的是,这似乎不是原因。我通过启动子进程。我刚刚进入Qt源代码,QProcess以bInheritHandles==false(
{sizeof(SECURITY_ATTRIBUTES),0,false}
)启动进程。如果杀死子进程可以释放会话,那么它仍然需要做些什么。你检查过孩子的把手了吗?有什么可疑的吗?另外,会话连接的性质是什么?它是套接字还是其他东西?只需在分叉新进程之前和之后比较双方(客户机和服务器)的netstat输出。要么文件句柄是从父进程继承的,要么它与QSqlDatabase heath check(如果有)有关系。否,在这种情况下,父进程将完全终止(通过procexp进行双重检查)。如果发生异常崩溃,父进程无法终止子进程,因为它会突然停止执行(没有可以处理的异常,只能立即终止)。可以通过Windows中的自动终止子进程,如中所述。如果主进程从任务管理的应用程序选项卡中被终止,则可以处理这种情况,并按照讨论的那样执行清理。自动终止子进程将非常好。但是,作业对象似乎没有完成其工作。。。我像你的链接中描述的那样实现了它;SetInformationJobObject和AssignProcessToJobObject返回true,但如果我杀死父进程,子进程将继续运行…感谢您的想法。但是,我认为这不是我的问题:服务器确实知道客户端消失了——如果我通过任务管理器终止子进程,服务器上的数据库会话将立即关闭。因此,我的问题是,为什么子进程首先让会话保持活动状态。服务器“知道”:如果会话处于活动状态,则首先将等待完成,然后将继续回滚未限制的工作,并且状态将在v$session中被终止。2.服务器不知道:可能是不同类型的终止(在UNIX系统上,您有诸如ABORT、KILL、TERM等信号),如果跟踪这些信号以及之后如何处理这些信号,则可能会出现另一种复杂情况。即使是仅选择,终止会话的任务可能需要很长时间。但问题似乎不是会话的清理。可以观察到两个事实:(1)只要子进程存在,服务器上的会话也会存在(甚至超过几天)。(2) 如果子进程被杀死,服务器的会话也会关闭。所以我的问题仍然是:为什么子进程在数据库服务器上保持会话的活动状态,即使它没有任何与数据库相关的东西呢。子进程从未打开或与数据库连接有关。