dongshen9686 2014-11-12 21:50
浏览 9
已采纳

如果另一个代码块失败,则PDO回滚

I'm trying to rollBack a PDO transaction based on the results of another block of code. This works great if the DB insert fails but if the "other stuff" throws an exception, it's not rolling back the commit. What am I doing wrong?

PHP version 5.4, database is MS SQL

<?php
    try {   
        $dbh = new PDO($dataSource);
        $dbh->beginTransaction();
        $sql = "INSERT INTO $table
                    (field1, field2, etc)
                VALUES
                    (:field1, :field2, :etc)"
        $stmt = $dbh->prepare($sql);
        $stmt->bindParam(':field1', $data["field1"]);
        $stmt->bindParam(':field2', $data["field2"]);
        $stmt->bindParam(':etc', $data["etc"]);
        $stmt->execute();
        $dbh->commit();

        //do some other stuff which can throw an Exception
    } catch (Exception $e) {
        //make sure we have something to roll back
        try { $dbh->rollBack(); } catch (Exception $e2) {}
        $log->logFatal("Error: controller.inc.php: " . $e->getMessage());
    }   
?>
  • 写回答

1条回答 默认 最新

  • doudong7256 2014-11-12 23:23
    关注

    Calling commit() effectively completes the open transaction begun earlier by beginTransaction(), so following the call to commit() there is no database action remaining to rollBack().

    If you have other code you want to run following a successful commit, you can check its return value in an if() block. PDO::commit() will return FALSE if the commit action itself fails, so you can prevent your mail action when it does by throwing another exception.

    try {
      $dbh = new PDO($dataSource);
      $dbh->beginTransaction();
      // etc...
      // etc...
    
      // Attempt to commit, and do other actions if successful
      if ($pdo->commit()) {
        // Do other actions
        // mail, etc...
      }
      else {
        // Otherwise, throw another exception which your catch {} will handle
        throw new Exception('Transaction was not committed');
      }
    } catch (Exception $e) {
      // Docs are unclear on whether rollBack() will throw an error on failure
      // or just return false. It is documented to throw an exception if 
      // no transaction is actually active.
      try { $pdo->rollBack(); } catch (Exception $e2) {}
        // Log your error, either a normal PDO error, or failed commit()...
        $log->logFatal("Error: controller.inc.php: " . $e->getMessage());
      }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 孟德尔随机化结果不一致
  • ¥20 求用stm32f103c6t6在lcd1206上显示Door is open和password:
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法