phpBB sql事务函数不工作


phpBB sql transaction function not working

我使用的是phpBB,但这段代码没有按预期工作。它只是使用phpBB sql_transaction函数来启动一个sql事务,然后提交它。但异常应该在执行到一半时抛出,并使用相同的函数发出回滚。

但是,回滚从未发生。查询1和2生效,我无法使它们回滚。

文档指出,如果出现sql错误,它将自动发出回滚,但如果出现php错误,例如超时或其他错误,我将尝试回滚。

我使用的是MySQL 5.7、phpBB 3.0.11和php 5.6。

有人能指出这个问题吗?

$db->sql_transaction('begin');
try {
    $sql = 'UPDATE aaa_temp SET method = "a" WHERE id = 1';
    $db->sql_query($sql);
    $sql = 'UPDATE aaa_temp SET method = "b" WHERE id = 2';
    $db->sql_query($sql);
    throw new Exception('OMG TOTAL ERROR');
    $sql = 'UPDATE aaa_temp SET method = "c" WHERE id = 3';
    $db->sql_query($sql);
} catch (Exception $ex) {
    $db->sql_transaction('rollback');
    trigger_error($ex->getMessage(), E_USER_ERROR);
}
$db->sql_transaction('commit');

提前感谢!我知道这一定是非常简单和愚蠢的事情,但如果需要更多细节,请告诉我。

编辑:很明显,我说的是MySQL中的SQL事务。

事实证明,我试图回滚更新的表使用的是MyISAM存储引擎,它不支持事务。

具有讽刺意味的是,phpBB就是这样构建它们的。sql_transaction('rollback')返回true,因为回滚确实有效,只是没有注意到SQL关于数据未回滚的警告。

通过在MySQL中启用general_query_log,可以确切地看到这个函数在后台做了什么:

SET AUTOCOMMIT=0;
UPDATE aaa_temp SET method = "a" WHERE id = 1;
UPDATE aaa_temp SET method = "b" WHERE id = 2;
ROLLBACK;
SET AUTOCOMMIT=1;

因此,由于我混合了MyISAM和InnoDB表,对后者的更改被回滚,而对前者的更改则没有。

您对异常的工作方式有误解。如果您有一个try{...}catch(...){...}块,并且在try{...}部分的某个地方抛出了异常,那么这是一个信号,表明您的代码流将跳到catch(...){...}块的开头。

在引发异常之前发生的所有代码都会发生。只有在异常之后的try块内的代码不会发生。没有rollback可以消除以前完成的所有过程,因为这对php开发人员来说非常(异常)困难。想象一下,如果你的php代码做了一些类似于发送电子邮件的事情。当电子邮件已经发送时,您希望如何进行回滚?因此,回滚不会发生。