Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP,异常是如何工作的?_Php_Exception_Transactions - Fatal编程技术网

PHP,异常是如何工作的?

PHP,异常是如何工作的?,php,exception,transactions,Php,Exception,Transactions,我知道什么是例外,我知道什么时候使用它们,但今天,我读了这个博客。它有下面的代码 require('autoload.php'); function foo($db, $data) { $db->beginTransaction(); foreach ($data as $row) { $db->insert($row); } $db->commit(); } $db = db::factory(); $data = da

我知道什么是例外,我知道什么时候使用它们,但今天,我读了这个博客。它有下面的代码

require('autoload.php');

function foo($db, $data) {
    $db->beginTransaction();

    foreach ($data as $row) {
        $db->insert($row);
    }

    $db->commit();
}

$db = db::factory();
$data = data::factory();

try {
    foo($db, $data);
} catch (Exception $e) {}

$db->insert(data::finalData());
根据该程序,data::finalData()应独立于foo()是否成功进行存储。不幸的是,事实并非如此:如果foo()内的循环中有什么东西抛出,那么将有一个打开的事务。最终数据现在成为该事务的一部分。由于没有进一步的处理,PHP将在程序结束时清理并自动回放事务

令人困惑的是,
最终数据现在成为该事务的一部分。
这与我对异常的理解相冲突,我知道异常是从捕获时调用
throw
的位置开始执行的,在本例中,在foreach中的某个位置,继续执行到foo函数的末尾执行
$db->commit()
,同时有效地关闭db事务。
根据这一观察,最终数据不应该像作者所说的那样成为事务的一部分。

commit指令是函数
foo()中的最后一个指令。
。如果引发异常(这只能发生在函数内部,因为try-catch块只包含对该函数的调用),那么该函数代码显然不会被处理到最后。因此不执行提交,事务“挂起”

执行在catch块中进行(该块为空,因此异常被“吞没”),然后在catch块之后正常进行,并执行“final data”指令。因此函数中的commit指令永远不会执行,事务仍然接受语句。这就是为什么“最终数据”会成为该事务的一部分


捕获异常后,执行不会以某种方式跳回!这就是异常的全部要点:立即离开失败的代码并返回到调用/控制范围

如果抛出异常,则事务显然不会提交。这意味着代码段中的最后一行将插入“最终数据”,作为(尚未)提交事务的一部分。这是因为捕捉到异常并恢复正常处理。仅此而已。@arkascha我想知道,当异常在异常上方抛出一行时,为什么不执行
$db->commit()
。或者通常情况下,执行在捕获异常之后开始啊,好吧,对不起,我不知道你问异常是如何工作的。。。commit指令是函数中的最后一个指令。如果引发异常(这只能发生在函数内部,因为try-catch块只包含对该函数的调用),那么该函数代码显然不会被处理到最后。因此,没有进行任何提交。相反,执行在catch块中进行(该块为空,因此异常被“吞没”),然后在catch块之后继续执行并执行“final data”指令。捕获异常后,执行不会以某种方式跳回!这很有帮助。如果你能确定答案,贴上答案。