【问题标题】:KO3, PostgreSQL, Transactions, and PDOExceptionKO3、PostgreSQL、事务和 PDOException
【发布时间】:2010-09-17 17:40:17
【问题描述】:

我遇到了一个问题,希望能得到一些帮助。我正在使用以下内容:

Kohana 3.0.7
PostgreSQL 8.4
PostgreSQL 中的事务使用

$db->query(NULL, 'BEGIN', FALSE)  
$db->query(NULL, 'ROLLBACK', FALSE);  
$db->query(NULL, 'COMMIT', FALSE);   

问题是,当我向数据库发送一个导致事务中出现 postgres 错误的查询时,我的系统会冻结。当我将相同的查询发送到数据库而不将其包装在事务中时,会按预期报告 PDO 错误。这是一个例子:

第一个示例工作正常,重复键值违反唯一约束“pk_test_table”错误返回:

$query = DB::query(Database::INSERT, 'INSERT INTO test_table (test_table_id, test_table_val) VALUES (:id, :value)';
$query->param(':id', 1);
$query->param(':value', "test value");

try 
{
    $result = $query->execute($db);
} 
catch (Exception $e) 
{
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}           

第二个例子导致我的系统死机(我不知道这是一个无限循环,还是其他一些死机):

$db->query(NULL, 'BEGIN', FALSE);

$query = DB::query(Database::INSERT, 'INSERT INTO test_table (test_table_id, test_table_val) VALUES (:id, :value)';
$query->param(':id', 1);
$query->param(':value', "test value");

try 
{
    $result = $query->execute($db);
} 
catch (Exception $e) 
{
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}           

$db->query(NULL, 'ROLLBACK', FALSE);

如您所见,唯一的区别是第二个示例包含在事务中。

对正在发生的事情有任何想法吗?有什么建议可以尝试吗?

【问题讨论】:

    标签: exception postgresql transactions kohana-3


    【解决方案1】:

    我找到了解决此问题的方法。不确定这是否是 PDO 或工具集的其他部分中的错误,但我正在解决的问题如下:

    $exception_exists = FALSE;
    
    $db->query(NULL, 'BEGIN', FALSE);
    
    $query = DB::query(Database::INSERT, 'INSERT INTO test_table (test_table_id, test_table_val) VALUES (:id, :value)';
    $query->param(':id', 1);
    $query->param(':value', "test value");
    
    try 
    {
        $result = $query->execute($db);
    } 
    catch (Exception $e) 
    {
        echo 'Caught exception: ',  $e->getMessage(), "\n";
        $exception_exists = TRUE;
    }           
    
    if (!$exception_exists)
    {
        $db->query(NULL, 'ROLLBACK', FALSE);
    }
    

    通过在 catch 中添加变量 $exception_exists 我可以在没有异常的情况下执行该操作。如果出现异常并且我尝试 ROLLBACK 或 COMMIT 然后我得到冻结行为。

    这暂时有效,但我不会称之为优雅。

    【讨论】:

    • 将 ->query(NULL, 'COMMIT', FALSE) 添加到 try 部分,并将 ->query(NULL, 'ROLLBACK', FALSE) 添加到 catch()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 2012-02-15
    • 2016-03-29
    相关资源
    最近更新 更多