在我们的服务器/客户端设置中,我们遇到了一些奇怪的行为。客户端是一个C / C ++应用程序,它使用OCI连接到Oracle服务器(使用OTL库)。
数据库服务器时不时会死掉(是的,这是核心问题,但是从应用程序端我们无法解决它但无论如何都必须处理它),机器不再响应了新的请求/连接,但现有的请求/连接,如Oracle连接,不会丢弃或超时。发送到DB的查询再也不会成功返回。
Oracle提供了哪些可能性(如果有)来检测来自客户端应用程序端的这些停滞连接并以一种或多或少安全的方式恢复?
答案 0 :(得分:3)
这是Oracle中的一个错误(或称之为功能),直到11.1.0.6,他们说Oracle 11g第1版(补丁11.1.0.7)上的修补程序有修复。需要看到。 如果它发生,你将不得不取消(杀死)执行此操作的线程。 虽然不是很好的方法
答案 1 :(得分:1)
在我的所有数据库模式中,我都有一个包含一个常量记录的表。只需通过简单的SQL请求定期轮询此表。所有其他方法都不可靠。
答案 2 :(得分:0)
OTL中有一个set_timeout
API可能对此有用。
编辑:实际上,忽略它。 set_timeout
不适用于OCI。请查看here中的set_timeout
说明,其中描述了可与OCI一起使用的技术
答案 3 :(得分:0)
有一种手动方法可以避免这种情况。您可以在每个指定的持续时间之后打开防火墙并执行ping数据库之类的操作。这样,数据库连接就不会丢失。
主意
If (current_time - lastPingTime > configuredPingTime)
{
//Dummy query
select 1 from dual;
}
答案 4 :(得分:0)
听起来你需要触发对数据库的查询(例如SELECT * FROM dual;
),然后如果数据库在指定的时间内没有响应,则假设服务器已经死亡并做出相应的反应。我担心我不知道C / C ++,但是你可以使用多线程来触发语句然后等待响应,而不会挂起应用程序吗?
答案 5 :(得分:0)
这很有效 - 我已经完成了你正在寻找的东西。 有父进程(A)创建子进程(B)。子进程(B)连接到数据库, 执行查询(类似于“从a_table中选择1”) - 如果您避免使用“双重”并创建自己的表格,您将获得更好的性能。如果(B)成功,那么它会写出它成功并退出。 (A)正在等待指定的时间。我用了15秒。如果(A)检测到(B)仍在运行 - 那么它可以假设数据库已挂起 - 它会杀死(B)并采取必要的行动(就像用手机通过短信给我打电话)。
如果您将SQL * NET配置为使用超时,您可能会注意到大型查询会因此而失败。 OCI set_timeout配置也会导致这种情况。