使用PDO事务并尝试catch和Why?
时,首选语法是什么?$dbh->beginTransaction();
try {
} catch (Exception $e) {
}
或
try {
$dbh->beginTransaction();
} catch (Exception $e) {
}
答案 0 :(得分:3)
现有的答案似乎表明,由于$dbh->beginTransaction()
可以抛出PDOException
,它应该在实际交易代码的同一try
块中,但这意味着{{1代码本身是错误的,因为它可以在没有事务的情况下调用rollBack()
,这也可以引发另一个rollBack()
。
正确的逻辑顺序是,在创建事务后,将要在一个事务中执行的代码放在一个catch块中。您还可以在继续之前检查PDOException
的返回是否为beginTransaction()
。在调用true
之前,您甚至可以检查数据库会话是否在事务中。
rollback()
请记住,至少在理论上,您仍然可以从if ($dbh->beginTransaction())
{
try
{
//your db code
$dbh->commit();
}
catch (Exception $ex)
{
if ($dbh->inTransaction())
{
$dbh->rollBack();
}
}
}
和beginTransaction()
获取异常,因此我将其放在一个单独的函数中,并将调用括在另一个{{1}中阻止。
你也可以冒泡你抓起它的异常并将所有异常记录在一个地方。但请记住,一些例外可能是数据完整性错误,例如重复键或无效的外键,这不会是数据库错误,但很可能是代码中的错误。
使用这种方法,这里要记住的主要事情是两个rollBack()
块的目的略有不同。内部的一个纯粹是为了确保在一个事务中以原子方式执行和提交多个查询,如果发生某些事情,它们将被回滚。外部try-catch
将检测错误情况并记录它,或者如果您的数据库出现问题,您可以执行任何操作。
答案 1 :(得分:0)
try {
$dbh->beginTransaction();
} catch (Exception $e) {
}
只是因为当您尝试开始交易时可能会抛出异常。
请注意,您可以在初始尝试中放置另一个try catch块。
答案 2 :(得分:0)
第二个通常最有意义。由于您可能并不总是知道导致事务失败的原因,您可能希望catch中有可用的回滚(并且可能是提交)逻辑,因此您需要将beginTransaction()
放在try中。
除try/catch
外,请确保设置错误模式属性:
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
如果有的话,你应该抓住PDOExecption
,因为你不应该以同样的方式处理所有异常。
try {
$dbh->beginTransaction();
//do stuff
$dbh->commit();
} catch (PDOException $e) {
$dbh->rollBack();
//...
throw $e;
}
但是如果您仍然想要捕获其他异常,请添加更多catch块:
try {
....
} catch (PDOException $e) {
//handle pdo exception
}catch (Exception $ex) {
//handle others differently
}