这是我的代码结构:
// 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;
}
何时执行该查询?你知道,我的脚本完全符合预期。但我想知道怎么样?如您所见,if - else
之前有一个commite()
声明;此外,if
和else
的块中都有die;
。据我所知,这条线永远不会执行:
$dbh_conn->commit();
因为它前面有一个die
。但令人惊讶的是我的代码也可以运行。以下是所有可能的输出:
one
作为value
表格中的标记存在,则会打印resend_pass
。two
在value
表中没有作为令牌存在,则会打印resend_pass
。three
(如语法SQL错误) 请参阅?一切都很好。但是怎么样?何时执行commit()
函数?在那些die
之前?
注意: resend_pass
的引擎是 innoDB 。
答案 0 :(得分:1)
在调用execute()
时执行查询(请注意query()
调用execute()
)。
如果查询更改了支持事务的表中的数据,则在释放PDO对象时将回滚更改,因为该对象超出范围或脚本终止并清除。这是由于PDO代码,而不是MySQL。
如果查询更改了不支持事务的表中的数据(例如MyISAM表),则更改在执行时是永久性的,并且无法回滚。
有一些SQL statements that perform an implicit commit。即使您的脚本在调用commit()
之前死亡,它们也会在执行后立即成为永久性的。
正如@MarcB所提到的,您的示例显示了只读SELECT
语句。如果您使用INSERT
/ UPDATE
/ DELETE
,则会更容易测试行为。