KO3、PostgreSQL、事务和 PDOException

发布于 2024-09-24 01:58:50 字数 1308 浏览 3 评论 0原文

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

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);

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

对正在发生的事情有什么想法吗?对于尝试的事情有什么建议吗?

I've run into an issue that I'm hoping to get a little help on. I'm using the following:

Kohana 3.0.7
PostgreSQL 8.4
Transactions in PostgreSQL using

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

The issue is that when I send a query to the database that results in a postgres error within a transaction my system freezes up. When I send the same query to the database without wrapping it in a transaction the PDO error is reported back just as expected. Here is an exmaple:

This first example works fine and duplicate key value violates unique constraint "pk_test_table" error is returned:

$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";
}           

This second example causes my system to freeze (I can't tell if it's an infinite loop, or some other freeze):

$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);

As you can see the only difference is that the second example is wrapped in a transaction.

Any ideas on what is going on? Any suggestions for things to try?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ヅ她的身影、若隐若现 2024-10-01 01:58:50

我找到了解决该问题的方法。不确定这是否是 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 ,如果没有异常,我就可以采取行动。如果出现异常并且我尝试回滚或提交,则会出现冻结行为。

这目前有效,但我不会称其为优雅。

I found a way to work around the issue. Not sure if this is a bug in PDO or some other part of the tool set but what I'm doing to work around is the following:

$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);
}

By adding the variable $exception_exists in the catch I can then act of that if there is no exception. If there is an exception and I try to ROLLBACK or COMMIT then I get the freezing behavior.

This works for now but I wouldn't call it elegant.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文