这里是我的代码结构:PDO事务API如何工作?
// db connection here
try {
$dbh_conn->beginTransaction();
$stm = $dbh_conn->prepare("SELECT user_id FROM resend_pass WHERE token = ?");
$stm->execute(array('value'));
$num_rows = $stm->fetch(PDO::FETCH_ASSOC);
if($num_rows) {
echo 'one'; die;
} else {
echo 'two'; die;
}
$dbh_conn->commit();
} catch(PDOException $e) {
$dbh_conn->rollBack();
echo 'three'; die;
}
正是在这个查询执行?你知道,我的剧本完全按照预期工作。但我很好奇,怎么样?如您所见commite()
之前有if - else
声明; if
和else
也在其块中有die;
。因此,作为据我所知,这行永远不会执行:
$dbh_conn->commit();
因为有切切实实的前一个die
。但令人惊讶的是我的代码也可以工作。这里是所有可能的输出:
- 它打印
one
如果value
存在作为resend_pass
表的令牌。 - 如果
value
在resend_pass
表中不存在作为令牌,则它将打印two
。 - 它打印
three
如果有错误(如语法SQL错误)
看到了吗?一切都好。但是如何?当commit()
函数执行时?在那之前die
?
注:的resend_pass
发动机是InnoDB的。
当php退出时,它会清理,这意味着它从数据库中断开。 mysql会看到并发出回滚来清除连接周围的任何“垃圾”。 '死'立即杀死剧本。除非你注册了关闭函数,否则你的提交调用永远不会有机会执行。 –
@MarcB *“您的提交调用永远不会得到执行的机会”* - 错误。正如我所说,该查询执行并且“if($ num_rows){”根据该查询的结果执行。 –
这有什么关系? PHP不会时间旅行。仅仅因为在脚本的“未来”某处有一个“死亡”命令并不意味着php将拒绝运行该脚本。它一行一行地运行代码,完全按照代码说的去做。它运行你的查询。它获取结果。它会测试结果,那么它可能会“死亡”。 –