2015-01-30 2 views
5

Я пробовал несколько различных циклов try/catch, чтобы попытаться решить проблемы автоматически, но они всегда кажутся причиной смерти программного обеспечения.Повторите попытку/улов, когда он сбой

$doLoop = true; 

while ($doLoop) { 

    try { 
     //do a thing 
     insertIntoDb($data); 
    } catch (Exception $e) { 
     //try again 
     insertIntoDb($data); 
     //write error to file 
     writeError($e); 
    } 
} 

Вот моя оригинальная попытка/улов.

Проблема в том, что сервер MySQL «уходит», и мне нужно поймать это исключение и продолжать повторять попытку, пока он не вернется.

Что я могу изменить здесь, чтобы это продолжало повторять попытку до тех пор, пока не будет успешным?

+1

вы были очень близки к решению :) – dynamic

+1

Я умолял вас заглянуть в _why_ ваш сервер MySQL «уходит». Одно определение безумия пытается повторять одно и то же снова, ожидая разные результаты. – sjagr

+1

Если ваш db иногда «уходит», тогда ваше решение не должно содержать повторения в PHP, необходимо исправить проблему с подключением. Этот код представляет собой бесконечный цикл, ожидающий своего существования. –

ответ

10

использовать разрыв в качестве последнего оператора в вашем try блоке оставить бесконечный цикл только на успех:

while (true) { 
    try { 
     //do a thing 
     insertIntoDb($data); 
     break; 
    } 
    catch (Exception $e) { 
     writeError($e); 
    } 
    // sleep 200ms to give the MySQL server time to come back up 
    usleep(200000); 
} 

Вы также можете ограничить число повторных попыток с помощью for петли вместо того, чтобы:

// do 3 retries before aborting finally 
for ($i=1; $i <= 3; $i++) { 
    try { 
     //do a thing 
     insertIntoDb($data); 
     break; 
    } 
    catch (Exception $e) { 
     writeError($e); 
    } 
    // sleep 200ms to give the MySQL server time to come back up 
    usleep(200000); 
} 

Обратите внимание на вызов usleep():

Это важно, потому что в противном случае PHP-процесс займет все ресурсы (100% -ый процессор) при повторной попытке как можно быстрее. Вы можете настроить значение в соответствии с вашими потребностями. (возможно, 200 мс слишком длинное или слишком короткое в вашем случае)

Также обратите внимание, что вам может потребоваться повторное подключение к базе данных MySQL при сбое! В моем примере я не использовал код для этого случая.

2

Это будет работать только в том случае, если ваша функция insertIntoDb вызовет исключение. Если вы используете функции mysql *, то это не сработает.

После insertIntoDb($data); вы должны установить $doLoop = false

+0

Я использую PDO для этого. Будет ли это работать? –

+0

Если вы передаете исключение PDO, тогда да. Ваша функция 'insertIntoDb()' не должна содержать try-catch – PKeidel

+0

Хорошо, отлично. Спасибо. –

Смежные вопросы