【问题标题】:Why doesn't PHP's oci_connect return false?为什么 PHP 的 oci_connect 不返回 false?
【发布时间】:2011-02-24 17:06:50
【问题描述】:

我有一种情况,我们有两个相互同步的生产数据库。服务器一被认为是主要的。有时由于维护或灾难,服务器 2 会成为主服务器。

在我们的某些代码中,这意味着我们必须手动进入并编辑数据库连接的服务器名称。我觉得这很烦人,所以我写的最后一件事是我将两者的服务器信息放入并设置了一个循环。如果 oci_connect 在服务器 1 上失败 3 次,它将转到服务器 2。如果服务器 2 失败 3 次,它将通知用户无法建立连接。

在我们遇到切换服务器的大多数情况下,这都能正常工作。例如,昨天,它运行良好。今天没有。它只是坐着无休止地旋转。 PHP 错误日志中没有错误。没有失败继续前进。没有错误输出到屏幕。 5分钟内什么都没有。

所以我不得不手动编辑愚蠢的配置文件。

我问可能有什么不同,我被告知“昨天数据库已关闭,但服务器没有。今天服务器已关闭。”好的...?但我看不出有什么区别。如果 oci_connect 无法与服务器建立任何类型的通信,我希望它返回 false。我希望它超时和错误。当它从服务器接收到错误代码时,不仅仅是传递它。例如,如果出现网络问题怎么办?

这是 oci_connect 中的一个错误,还是我们的 PHP 配置中的某些东西有可能给 oci_connect 一个疯狂的长时间超时?

如果它是一种“错误”,有什么方法可以检查服务器是否首先启动?像 ping 一样? (当然,当我通过命令提示符执行 ping 操作时,我得到了 Server One 的响应,然后被告知“它现在回来了”,尽管我对此时间持怀疑态度。)

无论如何,如果有人能阐明为什么 oci_connect 可能会无休止地运行而不会失败,以及如何防止它这样做,我将不胜感激。

-- 编辑: 我的代码看起来像 PHP.net 上的示例,只是在某些循环中。

 $count = count($servers);
 for($i = 0; $i < $count; $i++){
      if((!isset($connection)) || ($connection == false)){
           // Attempt to connect to the oracle database
           $connection = @oci_connect($servers[$i]["user"], $servers[$i]["pass"], $servers[$i]["conid"]) or ($conn_error = oracle_error());
           // Try again if there was a failure
           if(($connection == false) || (isset($con_error))){
                // Three (two more) tries per alternative
                for($j = $st; $j < $fn; $j++){
                     // Try again to connect
                     $connection = @oci_connect($servers[$i]["user"], $servers[$i]["pass"], $servers[$i]["conid"]) or ($conn_error = oracle_error());
                } // for($j = 2; $j < 4; $j++)
           } // if($connection == false)
      } // if(!isset($connection) || ($connection == false))
 } // for($i = 0; $i < $count; $i++)

【问题讨论】:

  • oci_connect 应该在失败时返回 false。你的连接脚本是什么样的?
  • 我同意。它有时会在失败时返回错误。代码已经按预期工作了好几次,直到有一天我遇到了这个问题。有人告诉我,“昨天数据库宕机了,但服务器没有。今天服务器宕机了。”是工作日和非工作日的区别。

标签: php database oracle timeout


【解决方案1】:

你能确认它没有返回 false 吗?它可能只是在等待连接时阻塞? (如果你这样做var_dump(oci_connect(...))会发生什么?

来自 php.net 的documentation

如果你想指定一个连接 有网络时超时 问题,你可以编辑客户端 (例如 PHP 端)sqlnet.ora 文件和 设置 SQLNET.OUTBOUND_CONNECT_TIMEOUT。 这设置了时间上限 建立连接权 通过数据库,包括时间 尝试连接到其他 服务。它可以从 Oracle 10.2.0.3 及以上版本。

在 Oracle 11.1 中,稍微 更轻的解决方案 引入了 TCP.CONNECT_TIMEOUT。 它也是一个 sqlnet.ora 参数。它 仅限制 TCP 连接 成立时间,主要是 出现连接问题的地方。

客户端 sqlnet.ora 文件应该是 放在与 tnsnames.ora 文件。

另外,您可能想查看FAN on this page... 看起来它可能完全符合您的要求(但我没有这方面的经验,所以我不确定它是否真的适合您)。

【讨论】:

  • 谢谢。我已经阅读并正在研究这两个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 2022-11-20
  • 2014-11-17
  • 2014-03-11
  • 2019-07-12
相关资源
最近更新 更多