为什么PHP的oci_connect不返回false?

时间:2010-05-27 14:41:48

标签: php database oracle timeout

我有一种情况,我们有两个生产数据库,彼此同步。 Server One被认为是主要的。有时由于维护或灾难,服务器二将成为主要的。

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

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

然后我不得不手动编辑愚蠢的配置文件。

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

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

如果它是某种“bug”,我可以通过某种方式检查服务器是否先出现?像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++)

1 个答案:

答案 0 :(得分:3)

你能证实它没有返回假吗?在等待连接时它可能只是阻塞吗? (如果你做var_dump(oci_connect(...))会怎么样?

直接来自php.net的documentation

  

如果要指定连接   有网络时超时   问题,你可以编辑客户端   (例如PHP方面)sqlnet.ora文件和   设置SQLNET.OUTBOUND_CONNECT_TIMEOUT。   这设置了上限时间   建立连接权   通过DB,包括时间   试图连接到其他人   服务。它可以从   Oracle 10.2.0.3以后。

     

在Oracle 11.1中,略有一点   重量轻的解决方案   引入了TCP.CONNECT_TIMEOUT。   它也是一个sqlnet.ora参数。它   仅限于TCP连接   建立时间,主要是   可以看到连接问题。

     

客户端sqlnet.ora文件应该是   放在同一目录下   tnsnames.ora文件。

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