PDO 中的事务在哪里回滚?

Posted

技术标签:

【中文标题】PDO 中的事务在哪里回滚?【英文标题】:Where to rollback a transaction in PDO? 【发布时间】:2011-03-22 01:20:03 【问题描述】:

我的问题是,我有一个来自这个链接is my database overdesigned?的数据库设计

edit* 好的,也许使用事务?但是如果失败了我应该把回滚放在哪里?

 $dbConnect->beginTransaction();
 $RegisterInsert = $dbConnect->prepare("INSERT INTO companies (
    `name`, `address`, `email`, `phone`, `link`, `verified`) VALUES (
    :name, :address, :email, :phone, :link, :verified)");
    $RegisterInsert->execute($RegisterData);

    $RegisterData2['CID'] = $dbConnect->lastInsertId();  

    $RegisterInsert = $dbConnect->prepare("INSERT INTO users_companies (
    `UID`, `CID`, `role`) VALUES (
    :UID, :CID, :role)");
    $RegisterInsert->execute($RegisterData2);
    $dbConnect->commit();

我应该把回滚放在哪里?

谢谢

【问题讨论】:

是的,我有点困惑我应该做交易吗? (我从来没有使用过)或者只是这样做,或者可能是一些加入?或者我可能错过的其他人,感谢帕斯卡发表评论:) 可能重复:***.com/questions/2167853/…、***.com/questions/2449132/…、***.com/questions/3225024/…、***.com/questions/1582834/… 是的,我知道,我不知道这个问题的最佳标题,请编辑它。 您应该始终使用具有适当错误处理的事务来确保您的数据库保持一致(如果您的第二次插入由于磁盘空间不足或 mysql 崩溃而失败会发生什么情况),但不是所有 MySQL 表类型支持使用事务...例如MyISAM 没有,InnoDB 有。 将 autoCommit 设置为 false 应该在事务结束时强制回滚,除非您明确提交......我不知道如果提交失败,是否会自动回滚。我更喜欢在代码中明确地显示我所有的提交和回滚,这样当其他开发人员查看它时就不会产生误解。 【参考方案1】:

事务应该以rollback()commit() 结束,(只有其中一个)

它通常与if...else 语句一起使用,因为逻辑上应该只执行其中一个。

$dbConnect->beginTransaction();

//somecode
//$dbConnect->execute( $someInsert );
//some more code
//$result = $dbConnect->execute( $someSelect );
//$nextRow = $result->fetchRow();

//either commit or rollback!
if( $someResultCheck == true )
    $dbConnect->commit();
else
    $dbConnect->rollback();

事务通常在查询涉及复杂逻辑时使用。

如果您使用的是 MySQL,请确保您没有对表使用 MyISAM 引擎,因为它不支持事务。

【讨论】:

除非 autoCommit 设置为 false,否则无法保证您的代码自动回滚 好的,我们应该在 RegisterInsert 上做一个 $someResultCheck 吗?我说的对吗? @kaskus:对。你只想在两个插入都成功执行时提交。所以你必须做$someResultCheck = $RegisterInsert->execute($stmt); @mark : autoCommit 仅对事务外的语句起作用,其中单个语句被包装在事务内。当您手动开始交易时,它不适用于其中。 @Kalyan - 感谢您的澄清。正如我在其他地方所说,我总是对显式事务启动和提交/回滚进行编码,因为这样就不会与其他开发人员阅读代码产生任何误解【参考方案2】:

一旦您知道整个事务将失败,那么您应该回滚到目前为止所做的事情并且不要尝试任何进一步的更新 - 所以在伪代码中:

 function do_updates(array updates)
  
    PDO->beginTransaction();
    foreach (updates as statement) 
       run statement
       if failed 
         PDO->rollback(); 
         return false;
       
    
    return PDO->commit();

HTH

C.

【讨论】:

以上是关于PDO 中的事务在哪里回滚?的主要内容,如果未能解决你的问题,请参考以下文章

PDO:事务不回滚?

PHP PDO 执行失败时事务会回滚吗?

PHP PDO事务回滚不起作用

PDO中的事务处理

事务、存储过程和 PDO

事务在休眠中不回滚