2013-09-30 63 views
2

我正在处理一些需要获取数据库资源的PHP代码,在运行期间将其标记为锁定,并在完成时将其标记为未锁定。锁在启动时通过更新表中的值而获得,并且当脚本由于任何原因而终止时,我已经注册了关闭函数以释放锁。在关机功能中捕捉异常

我遇到的问题是与服务器(Microsoft SQL数据库服务器)的连接在实时环境中似乎不可靠,而这似乎是异常脚本终止的常见原因。显然,当我没有连接时,我无法解锁数据库资源,但我至少希望能够处理失败干净地做到这一点。

以下是主要脚本的严重削减版本。

try { 
    echo "Connecting to server...\n"; 
    $obj_adaptor = get_remote_db(); 

    echo "Beginning sync...\n"; 
    if (FALSE != ($bol_locked = $obj_adaptor -> lock_server_db())) { 
     // Do work here 
    } else { 
     throw new RuntimeException ("Failed to obtain remote database lock!"); 
    } 
} catch (Exception $obj_ex) { 
    echo "Operation failed with an exception!\n\n"; 
    echo "Details: \n"; 
    echo $obj_ex -> getMessage() . PHP_EOL; 
    echo $obj_ex -> getTraceAsString() . PHP_EOL; 
} 

我的关机功能是这样的:

$arr_shutdown_func = function() { 
     global $bol_locked, $obj_adaptor; 
     if ($bol_locked) { 
     echo "Releasing lock...\n"; 
     try { 
      echo $obj_adaptor -> unlock_server_db()? 
       "Done\n": 
       "Failed to unlock database! Use force_remote_db_unlock script to force a database unlock\n"; 
     } catch (PDOException $obj_ex) { 
      echo "Failed to unlock database! Use force_remote_db_unlock script to force a database unlock\n"; 
     } 
     } else { 
     echo "No lock to release\n"; 
     } 
    }; 

// Set up ctrl-c listener 
if (function_exists ('pcntl_signal')) { 
    pcntl_signal (SIGINT, $arr_shutdown_func); 
    pcntl_signal (SIGTERM, $arr_shutdown_func); 

// Register shutdown functions 
register_shutdown_function ($arr_shutdown_func); 
set_exception_handler ($arr_shutdown_func); 

我在连接的情况下,希望丢失的脚本试图释放数据库锁时失败,呼应出的信息关于无法释放锁。

不过,我实际上得到的是:

PHP Fatal error: Uncaught exception 'Zend_Db_Statement_Exception' with message 'SQLSTATE[HY000]: General error: 20047 DBPROCESS is dead or not enabled [20047] (severity 1) [(null)]' in Zend/Db/Statement/Pdo.php:238

我试图找到它是否有可能捕获异常处于关机功能一个明确的答案,但没有多少运气至今所以我还在寻找。但是,如果可以在关闭函数中处理异常,我会很高兴知道我正在应用的方法有什么问题。

回答

0

我刚刚用一个简单的代码测试了这一点,并且在关闭函数之前我没有断开连接。

<?  
mysql_connect('localhost','xxx','xxx') or die(mysql_error()); 
mysql_select_db('xxx'); 
register_shutdown_function("s"); 

function s() { 
    echo 'xxxx'; 
    $qa = mysql_query('SELECT * FROM xxx') or die(mysql_error()); 
    while($q = mysql_fetch_array($qa)) { 
     print_r($q); 
    } 
} 
?> 

您使用的是哪个版本的PHP?

PHP 5.5.3 (cli) (built: Aug 23 2013 08:41:45) Copyright (c) 1997-2013 The PHP Group Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies

+0

PHP 5.4.6-1ubuntu1.4(cli)(built:Sep 4 2013 19:36:09)。另外我使用Zend_DB封装一个PDO数据库连接,所以它会抛出异常,而不是这样做。 – GordonM