我有一个C ++应用程序,它通过Qt QSqlDatabase
接口连接到Oracle数据库。主应用程序建立并使用与数据库的连接以及为不相关的其他porpuses启动子进程。为了明确这一点:子进程不使用任何与数据库相关的东西。
现在的问题是:如果主进程以一种不寻常的方式终止(它崩溃或被用户通过任务管理器杀死),我可以看到Oracle服务器上的数据库会话保持活动状态没有超时。但是,绝对可重复,在我手动终止子进程后,会话立即被取消。
当那些悬空,孤立的会话导致一些问题(服务器上达到最大会话数的最简单方法)时,我真的希望所有会话尽快关闭。
我现在的问题是:只是因为不相关的子进程仍处于活动状态,才能使会话在服务器上保持活动状态的机制是什么?如何控制此行为,即如果主应用程序进程终止,则告诉oracle客户端断开任何会话?
提前致谢!
答案 0 :(得分:2)
<强>更新强> https://bugreports.qt.io/browse/QTBUG-9350 和 https://bugreports.qt.io/browse/QTBUG-4465
在Windows上,子进程继承套接字和文件描述符,即使 inheritFileDescriptors 设置为 false < / p>
似乎该错误已在QT5中修复
关于Oracle线程问题的讨论:
https://community.oracle.com/thread/1048626
TL; DR; oracle服务器不知道&#34;客户已经消失了。
一些解决方案: 1.终端连接检测功能: http://docs.oracle.com/cd/B19306_01/network.102/b14213/sqlnet.htm#sthref474
2.我的建议是尝试实施一个连接池&#39;如果你使用QOCI驱动程序。或者您可以使用支持连接池的ODBC。
答案 1 :(得分:1)
在关闭数据库连接之前,看起来主进程未成功终止并等待终结代码某处的子进程终止。
从另一方面,异常终止子进程引发的异常情况成功传播到父进程,启动终结进程并关闭与Oracle的连接。
所以第一个建议是检查子进程是否正确地对kill()和terminate()调用作出反应,甚至父进程在异常终止的情况下尝试终止子进程。