哪种机制使Oracle会话在服务器上保持活动状态

Which mechanism keeps an Oracle session alive on the server?

本文关键字:服务器 活动状态 会话 机制 Oracle      更新时间:2023-10-16

我有一个C++应用程序,它通过Qt QSqlDatabase接口连接到Oracle数据库。主应用程序建立并使用与数据库的连接,同时启动不相关的其他porpus的子进程。为了明确这一点:子进程不使用任何与数据库相关的东西。

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

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

我现在的问题是:仅仅因为一个不相关的子进程仍然存在,就让会话在服务器上保持活动状态的机制是什么?我如何控制这种行为,即告诉oracle客户端在主应用程序进程失效时断开任何会话?

提前感谢!

更新https://bugreports.qt.io/browse/QTBUG-9350和https://bugreports.qt.io/browse/QTBUG-4465

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

看来QT5 中的错误已经修复


关于Oracle线程问题的讨论

https://community.oracle.com/thread/1048626

TL;DR;oracle服务器并不"知道"客户端已经消失。

一些解决方案:1.有一个终止连接检测功能:http://docs.oracle.com/cd/B19306_01/network.102/b14213/sqlnet.htm#sthref474

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

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

因此,第一个建议是检查子进程是否对kill()和terminate()调用做出了正确的反应,甚至在异常终止的情况下,父进程也会尝试终止子进程。