【问题标题】:Throwing an exception when there is transaction有事务时抛出异常
【发布时间】:2016-11-16 15:12:50
【问题描述】:

这是我的脚本:

try{

    $dbh_conn->beginTransaction();

    $user_id = $_POST['iuser_id'];
    $token   = hash('sha512', bin2hex(openssl_random_pseudo_bytes(16)).$user_id);

    $stmt = $dbh_conn->prepare("UPDATE resend_pass SET active = 0 WHERE user_id = ?");
    $stmt->execute(array($user_id));

    $stm = $dbh_conn
    ->prepare("INSERT INTO resend_pass(user_id, token, date_time)
                SELECT ?, ?, unix_timestamp()
                FROM dual
                WHERE NOT EXISTS( SELECT count(*) AS num_week,
                                    FROM resend_pass
                                   WHERE user_id   = ?  
                                     AND date_time > unix_timestamp() - 604800
                                  HAVING num_week > 11 ;");
    $stm->execute(array($user_id, $token, $user_id));

    // no row inserted (either there is lots of reuqests or duplicate token)
    if ( !$stm->rowCount() ) { throw new Exception('something is wrong'); }

    $dbh_conn->commit();

    /* sending an email contains reset_password_token here */

    $_SESSION["TopMSG"] = "<div class='msg_success'>has been sent</div>";
    header('location: ../login');
    exit;

} catch(Exception $e) {

    $dbh_conn->rollBack();

    $_SESSION["TopMSG"] = "<div class='msg_success'>$e</div>";
    header('location: ../login');
    exit;

}

如您所见,commit() 之前有一个 throw。可以吗?实际上,当我运行它时,它不起作用并抛出此错误:

致命错误: 在 C:\xampp\htdocs\myweb\others\login.php:341 堆栈跟踪:#0 C:\xampp\htdocs\myweb\application 中未捕获的异常“异常” \other.php(35): login->resend_password_check() #1 C:\xampp\htdocs\myweb\index.php(150): require_once('C:\xampp\htdocs...') #2 {main } 在 C:\xampp\htdocs\myweb\others\login.php 中抛出 if ( !$stm-&gt;rowCount() ) { throw new Exception('something is wrong'); }

我该如何解决?

【问题讨论】:

  • 你在使用命名空间吗?似乎您的代码没有找到您的 Exception 类。顺便说一句:在提交之前抛出异常是可以的。 PS.:我知道这不是上下文,但是在代码中退出并不好。让请求流优雅地结束

标签: php mysql pdo transactions throws


【解决方案1】:

php 致命错误无法捕获。

当你使用 pdo 时,不要写 throw new Exception('something is wrong'); 因为 PDO 已经有了这个表达式 PDOException

例如:

try{
    $dbh_conn->beginTransaction();
    .......
    .......
    $stm->execute(array($user_id, $token, $user_id));
    ......
    $dbh_conn->commit();

}catch(PDOException $e) {
    print_r($e->getMessage());//Show excption message
    $dbh_conn->rollBack();
    $_SESSION["TopMSG"] = "<div class='msg_success'>$e</div>";

    //header('location: ../login');
    exit;
}

【讨论】:

  • 错误 .. 我的查询是 INSERT .. SELECT 并且当没有插入行时它不会抛出异常。这就是我写throw的原因。
  • @Martin AJ PDO 捕获此错误 INSERT .. SELECT.Write print_r($e->getMessage());进入 catch 块,你会被说服
  • pdo 失败不是 php 致命的。它可以像其他任何东西一样被抓住。只有当 NOTHING 捕获到异常时它才会变得致命(如果您没有明确启用它们,无论如何都不会抛出)。
  • @Marc B Into question 说致命错误:...不是真的。致命错误被称为致命错误,因为它们是致命的。您无法从中恢复。PHP 没有提供常规方法来捕获致命错误并从中恢复。
猜你喜欢
  • 2020-09-24
  • 2015-10-03
  • 2013-05-24
  • 2018-03-17
  • 2014-11-30
  • 2017-03-11
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
相关资源
最近更新 更多