使用php重试数据库异常

时间:2015-06-17 07:58:40

标签: php exception mysqli

我一直在研究php抛出的异常 - mysqli&在下面创建了这个片段,尝试检查几次以查看临时故障是否导致数据库失败。如果是这样,它会尝试恢复。如果它不能那么它退出/结束。

现在虽然逻辑很好,但我无法找出为什么echo语句不会按照它们应该定期发生的原因。只有到最后(取决于在findMail()函数中抛出异常的方式),输出才会被抛出&这是正确的。抛出新的异常行可以随时更改为失败或最后一次传递。它设置为在代码段中传递最后一轮。如果有人可以指出我为什么回声没有按时间间隔显示输出,那就太棒了。

此外,我不确定这在生产中是好还是坏。对此的任何反馈都非常受欢迎。谢谢大家。

代码段:

<?php
$host        = 'localhost';
$user        = 'root';
$password    = '';
$database    = 'test';

// OPEN A CONNECTION TO THE DATA BASE SERVER AND SELECT THE DB

try
{
    $con = new mysqli($host,$user,$password,$database);
    if($con->connect_error)
    {
        throw new Exception("Goof Up");
    }   
    mysqli_set_charset($con, "utf8"); 
}
catch(Exception $e)
{
    echo $e->getMessage();
    exit;
}

// All well so far 

$cnt = 0;
if(findMail($con,$cnt)) echo "<br> Hurray !!";

function findMail($con,$cnt)
{
    try
    {   
        echo $cnt++."<br>";
        $query = "SELECT name, email from users";
        $stmt=$con->prepare($query);
        if($cnt < 3 ) throw new exception($cnt);
        if($stmt->execute())    
        {   
            $stmt->bind_result($name, $email);
            while ($stmt->fetch())
                {
                    $email = htmlspecialchars($email);
                    $name = htmlspecialchars($name);
                    echo $name.' ---- '.$email.'<br>'; 
                }       
        }
    }
    catch(Exception $e)
    {
        $cnt = (int)($e->getMessage());
//      echo $cnt;
        if($cnt === 4) { echo "Ending"; exit();} 
        sleep(5);
        findMail($con,$cnt);
    }   
    return true;
}
?>

2 个答案:

答案 0 :(得分:1)

在某些条件下使用ob_start和ob_flush时,它必须与浏览器渲染有关。

我注意到当我设置php header("Content-Encoding: none")来禁用gzip压缩时:

更新 - 添加了一个示例

<?php 
header("Content-Encoding: none"); 

ob_end_clean();
ob_start(); 

for($i=0;$i<5;$i++) 
{ 
    echo 'No. '.$i."<br>";
    ob_flush();
    flush();
    sleep(2);
}
?>

它正常冲洗。查看以下链接的更多详细信息

PHP Streaming/Output Buffering no longer working

For php flush - how to disable gzip for specific file?

答案 1 :(得分:0)

将此PHP脚本与sleep(X)一起使用可能会导致用户等到完成(成功与否)。

我建议通过AJAX调用脚本(例如jQuery.ajax([...])),因此前端不会被阻止。

更新 - 使用ajax的示例

文件:test.php

<?php
// verify if this is an ajax request (if, so exit the script before out)
if(isset($_GET['ajax'])) {

    $host        = 'localhost';
    $user        = 'root';
    $password    = '';
    $database    = 'test';

    // return result being parsed by JS through json_encode
    $result = array('data' => null, "error" => false);

   /**
    * function to return name and emails as array list
    */
   function findMail($con)
   {
        $data = null;
        $query = "SELECT username, uid from tbl_user";
        $stmt=$con->prepare($query);
        if($stmt->execute())
        {      
                $data = [];
                $stmt->bind_result($name, $email);
                while ($stmt->fetch())
                {
                        $email = htmlspecialchars($email);
                        $name = htmlspecialchars($name);
                        $data[] = array('name' => $name, 'email' => $email);
                }
        }
        return $data;
    }

    try
    {
        $con = new mysqli($host,$user,$password,$database);
        if($con->connect_error)
        {
                throw new Exception("Goof Up");
        }      
        mysqli_set_charset($con, "utf8");

        $result['data'] = findMail($con);
    }
    catch(Exception $e){
        $result['error'] = true;
    }

    echo json_encode($result);
    exit;
}
?>
<!DOCTYPE>
<head>
<title>TEST 1</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script type="text/javascript">

        $(function(){
                var retryCounter = 0;
                var repeatInterval = 3000;
                var repeatCall = function(){
                        if(retryCounter >= 3) {
                                console.log('max retries reached');
                                return;
                        }
                        console.log('Calling...');

                        $.ajax({
                                url: "test.php?ajax=1",
                                dataType: "json"
                        })
                        .done(function( result, textStatus, xhr ) {
                            // data = the json encoded result from errScript.php
                                console.log("received data from errScript.php");

                                if(!result) {
                                        console.log('STOPPED due to invalid/empty data');
                                        return;
                                }

                                // on error, retry and increase counter
                                if(result.error)
                                {
                                        setTimeout(repeatCall, repeatInterval);
                                        retryCounter++;
                                        return;
                                }

                                $.each(result.data, function(k, v){
                                        document.write(v.name + " --- " + v.email + "<br />");
                                });
                   }).fail(function(xhr, textStatus, err) { console.log('error'); });
                };

                setTimeout(function() { repeatCall(); }, repeatInterval);      
        });

   </script>

</head>
<body>
        <h1> TEST 1 </h1>
</body>  
</html>