Почему PHP oci_connect не возвращает false?

1

У меня есть ситуация, когда у нас есть две производственные базы данных, которые синхронизируются друг с другом. Server One считается первичным. Иногда из-за технического обслуживания или бедствия Server Two станет основным.

В некотором из нашего кода это означает, что нам нужно вручную войти и отредактировать имя сервера для соединений с базой данных. Я нахожу это раздражающим, поэтому последнее, что я написал, я помещал информацию о сервере для обоих и настраивал цикл. Если oci_connect провалился на сервере One 3 раза, он переместится на Server Two. Если Server Two провалился 3 раза, он уведомит пользователя о невозможности подключения.

Это отлично срабатывало, когда у нас была ситуация с переключением серверов. Вчера, например, он работал нормально. Сегодня этого не произошло. Он просто сидел и крутился бесконечно. Ошибка в журнале ошибок PHP. Нет отказа от перехода. На экран не выводится ошибка. Ничего в течение 5 минут.

Итак, мне пришлось вручную редактировать глупый файл конфигурации.

Я спросил, что может быть другим, и мне сказали, что вчера база данных была отключена, но не сервер. Сегодня сервер не работает ". Хорошо...? Но я не вижу различия. Я ожидал бы, что oci_connect вернет false, если не сможет установить какой-либо связи с сервером. Я ожидаю, что это будет тайм-аут и ошибка. Не просто передавать его, когда он получает код ошибки с сервера. Что, если есть сетевая проблема, например?

Является ли это ошибкой в ​​oci_connect или есть вероятность, что что-то в нашей конфигурации PHP дает oci_connect безумно длинный тайм-аут?

Если это своего рода "ошибка", есть ли способ проверить, первым ли сервер? Как пинг? (Конечно, когда я сделал 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++)
  • 0
    oci_connect должен возвращать false при сбое. Как выглядит ваш скрипт подключения?
  • 0
    Я согласен. И он возвращает ложь в случае неудачи. Код работал несколько раз, как и ожидалось, пока однажды я не столкнулся с этой проблемой. Мне сказали: «Вчера база данных не работала, но не сервер. Сегодня сервер не работает». была разница между рабочим днем и нерабочим днем.
Теги:
database
timeout

1 ответ

3
Лучший ответ

Можете ли вы проверить, что он не возвращает false? Возможно, это просто блокировка при ожидании соединения? (что произойдет, если вы выполните var_dump(oci_connect(...))?

Справа от php.net документация:

Если вы хотите указать соединение тайм-аут в случае наличия сети проблема, вы можете отредактировать клиентскую сторону (например, на стороне 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 на этой странице... Похоже, что он может делать именно то, что вы хотите (но У меня нет опыта в этом, поэтому я не уверен, действительно ли это подходит вам).

  • 0
    Спасибо. Я прочитал это и изучаю оба из них.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню