我正在使用phpBB并且此代码无法按预期工作。它只是使用phpBB sql_transaction
函数来启动一个sql事务,然后提交它。但是异常应该在中途抛出并使用相同的函数发出回滚。
但是,回滚永远不会发生。查询1和2生效,我无法让它们回滚。
documentation表示如果出现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事务。答案 0 :(得分:0)
事实证明,我试图回滚更新的表是使用MyISAM存储引擎,它不支持事务。
具有讽刺意味的是,这就是phpBB如何构建它们的具体方式。 <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<path id="connector" fill="none" stroke="black" stroke-width="10" />
</svg>
<div id="a">This is a regular HTML div.</div>
<div id="b">So is this.</div>
返回true,因为回滚确实有效,它只是没有收到有关未回滚数据的SQL警告。
通过启用MySQL中的sql_transaction('rollback')
以确切了解此函数在后台执行的操作来解决此问题:
general_query_log
因为我混合使用了MyISAM和InnoDB表,后者的更改正在回滚,而对前者的更改则没有。
答案 1 :(得分:-1)
您对例外的工作方式存在误解。如果你有一个try{...}catch(...){...}
块,并且在try{...}
部分内某处抛出异常,那么这就是你的代码流将跳转到catch(...){...}
块的开头的信号。
在抛出异常之前发生的所有代码都会发生。只有异常之后的try
块内的代码才会发生。没有rollback
发生消除之前完成的所有进程,因为这对于php开发人员来说非常(非常)困难。想象一下,如果你的PHP代码做了类似发送电子邮件的事情。您是否期望在电子邮件已发送后再进行回滚?因此,回滚不会发生。