【发布时间】:2016-11-19 05:03:20
【问题描述】:
这是我的代码结构:
// 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。但令人惊讶的是,我的代码也能正常工作。以下是所有可能的输出:
- 如果
value作为标记存在于resend_pass表中,它将打印one。 - 如果
value在resend_pass表中不作为标记存在,它会打印two。 - 如果有错误,它会打印
three(如语法 SQL 错误)
看到了吗?一切都好。但是怎么做? commit() 函数何时执行?在那些dies 之前?
注意:resend_pass的引擎是innoDB。
【问题讨论】:
-
当 php 退出时,它会清理,这意味着它与数据库断开连接。 mysql 将看到这一点并发出回滚以清除任何“垃圾”连接到处乱扔。
die立即杀死脚本。除非你注册了一个关闭函数,否则你的提交调用将永远没有机会执行。 -
@MarcB "你的提交调用将永远没有机会执行" -- 错误.. 正如我所说,该查询执行并且
if($num_rows) {执行基于该查询的结果。 -
有什么关系? php 没有时间旅行。仅仅因为在脚本的“未来”某处有一个“die”命令并不意味着 php 将完全拒绝运行该脚本。它逐行运行代码,完全按照代码所说的去做。它运行您的查询。它获取结果。它测试结果,然后它可能会
die. -
@MarcB 我只是想了解,我的脚本结构好吗?还是我应该改变它的结构?
-
按原样,没关系,尽管您可能不想依赖 php/mysql 在清理情况下进行回滚。也许由于某种原因,oracle 会在未来的某个 mysql 版本中反转逻辑并在关闭时提交未完成的事务。不明白为什么,这会非常愚蠢,但无论如何,逻辑从来都不是与 oracle 相同的句子。
标签: php mysql pdo transactions