带有 try catch 的 PDO 事务语法
Posted
技术标签:
【中文标题】带有 try catch 的 PDO 事务语法【英文标题】:PDO Transaction syntax with try catch 【发布时间】:2014-08-16 00:03:41 【问题描述】:使用 PDO 事务和 try catch 时首选的语法是什么?为什么?
$dbh->beginTransaction();
try
catch (Exception $e)
或
try
$dbh->beginTransaction();
catch (Exception $e)
【问题讨论】:
取决于你在catch
里面做什么
【参考方案1】:
try
$dbh->beginTransaction();
catch (Exception $e)
仅仅是因为在您尝试开始事务时可能会引发异常。
请注意,您可以在初始尝试中放置另一个 try catch 块。
【讨论】:
【参考方案2】:第二个通常最有意义。由于您可能并不总是知道什么会导致事务失败,因此您可能希望在 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;
但如果你仍然想捕获其他异常,请添加更多捕获块:
try
....
catch (PDOException $e)
//handle pdo exception
catch (Exception $ex)
//handle others differently
【讨论】:
【参考方案3】:现有的答案似乎表明,由于 $dbh->beginTransaction()
可能会抛出 PDOException
它应该在实际事务代码的同一 try
块中,但这意味着 rollBack()
代码本身将是错误的,因为它可以在没有事务的情况下调用rollBack()
,这也可能引发另一个PDOException
。
正确的逻辑顺序是在创建事务后将要在一个事务中执行的代码放在一个 catch 块中。您还可以在继续之前检查beginTransaction()
的返回值是否为true
。您甚至可以在调用rollback()
之前检查数据库会话是否处于事务中。
if ($dbh->beginTransaction())
try
//your db code
$dbh->commit();
catch (Exception $ex)
if ($dbh->inTransaction())
$dbh->rollBack();
请记住,至少在理论上,您仍然可以从 beginTransaction()
和 rollBack()
获得异常,因此我会将其放在单独的函数中,并将调用包含在另一个 try-catch
块中。
您还可以冒泡您发现的异常以捕获它并将所有异常记录在一个地方。但请记住,一些例外情况可能是数据完整性错误,例如重复键或无效外键,这不是数据库错误,但很可能是代码中的错误。
使用这种方法,这里要记住的主要事情是两个try-catch
块的用途略有不同。内部的纯粹是为了确保在一个事务中原子地执行和提交多个查询,如果发生某些事情,它们会回滚。外部try-catch
将用于检测错误情况并记录它,或者如果您的数据库有问题,您想要做的任何事情。
【讨论】:
以上是关于带有 try catch 的 PDO 事务语法的主要内容,如果未能解决你的问题,请参考以下文章
php 语法错误定位 try catch Throwable