2014-05-25 112 views
6

PHP PDO::commit()文档声明该方法在成功时返回TRUE或在失败时返回FALSE。这是否指beginTransaction()和commit()之间语句执行的成功或失败?PDO :: commit()成功或失败

例如,从文档:

$dbh->beginTransaction(); 
$sql = 'INSERT INTO fruit (name, colour, calories) VALUES (?, ?, ?)'; 
$sth = $dbh->prepare($sql); 

foreach ($fruits as $fruit) { 
    $sth->execute([ 
     $fruit->name, 
     $fruit->colour, 
     $fruit->calories, 
    ]); 
} 

$dbh->commit(); 

如果上述任何执行失败,将在commit()方法,由于原子事务的“全有或全无的基础”返回false?

+0

我真的不记得需要在代码库中提交,你有没有尝试过吗? – Jonast92

+0

我不确定我是否理解。手动交易的目的是确保多个报表都是成功的,或者没有。 –

+0

我认为你在想这件事。如果在这种情况下失败,那么很可能所有的都会失败,反之亦然。只需为代码添加适当的错误处理,并且如果您真的关心什么是失败,那么只需将其记录下来即可。我从来不必在服务器端代码中使用提交,我发现你不太可能必须这样做。 – Jonast92

回答

2

返回值基于pdo :: commit本身,而不是您要提交的事务。 当没有事务处于活动状态时,它返回FALSE,但每当它返回TRUE或FALSE时它不是很清楚。

事务中执行的查询本身会成功或失败。 使用Mr.Tk的例子,如果可能,事务将被提交,并且在“try”块中执行查询时没有发生错误,并且如果在“try”块内发生了错误,则回滚。

当只评估“try”块内执行的查询时,我个人会尝试捕获一个PDOException而不是一个正常的异常。

$dbh->beginTransaction(); 
try { 
    // insert/update query 
    $dbh->commit(); 
} catch (PDOException $e) { 
    $dbh->rollBack(); 
} 
0

我一直在做它喜欢的是:

$dbh->beginTransaction(); 

try { 
    // insert/update query 

    $dbh->commit(); 
} catch (Exception $e) { 
    $dbh->rollBack(); 
} 

并始终担任魅力! :)

所以我认为,在你的情况下,如果插入会失败的应用程序应该抛出一个异常,并提交甚至不会触发。

3

的关键部分是同时具有的try-catch仅做回滚是不需要设置PDO的异常模式,。因此,你的代码是好的,没有必要去改变它,如果你想要的是在失败回滚,只要你有这行的地方:

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

在出现故障的情况下,该脚本将被终止,连接关闭MySQL会很乐意为你回滚事务。

如果你仍然想手动回滚,你应该正确地做,而不是像其他答案中说的那样。确保

  • 你正赶上Exception,不PDOException,因为它什么都无所谓特定异常中止执行
  • 重新抛出异常回滚后,被通知的问题
  • 此外,表引擎支持交易(即对于Mysql,它应该是InnoDB,而不是MyISAM)。

该清单取自my article,您可能会发现在这个或许多其他方面也很有用。

+0

你确定吗?如果我执行10个不同的插入或更新,并在最后一个pdo引发异常,所有9个其他句子回滚? –

+0

我同意@CarlosGoce:如果没有明确的'begin/rollback'处理,它将不会回滚。但是,例外将有助于运行@TK所述的“回滚”。事实上,你甚至不回答关于'commit'的问题:如果你想取消以前发送的很多查询,如果出现任何错误,事务就很有用。 – Yvan

+0

@Yvan肯定会回滚,因为事务总是会以* close close *的形式回滚。但我宁愿同意使用交易,如果正确使用,尝试捕捉是有用的。 –