stack stack - 4 months ago 8
SQL Question

How can I handle errors when there is transaction?

Here is my code:

try {
$dbh_con->beginTransaction();

$stmt1 = $dbh_conn->prepare("UPDATE activate_account_num SET num = num + 1");
$stmt1->execute();

$stmt2 = $dbh_con->prepare("SELECT user_id FROM activate_account WHERE token = ?");
$stmt2->execute(array($token));
$num_rows = $stmt2->fetch(PDO::FETCH_ASSOC);

if ( $num_rows['user_id'] ){
$_SESSION['error'] = 'all fine';

} else {
$_SESSION['error'] = 'token is invalid';
}

$dbh_con->commit();

header('Location: /b.php');
exit();

} catch(PDOException $e) {

$dbh_con->rollBack();

$_SESSION['error'] = 'something is wrong';
header('Location: /b.php');
exit();
}


As you see, my script rollbacks all queries when there is a exception. But it doesn't rollback when
if ( $num_rows['user_id'] ){
is
false
. So how can I both rollback the queries and keep the error
'token is invalid'
when that condition is
false
?

Answer

Just throw an Exception and catch it like you already do. But instead of one catch statement have two:

try {
    $dbh_con->beginTransaction();

        $stmt1 = $dbh_conn->prepare("UPDATE activate_account_num SET num = num + 1");
        $stmt1->execute();

        $stmt2 = $dbh_con->prepare("SELECT user_id FROM activate_account WHERE token = ?");
        $stmt2->execute(array($token));
        $num_rows = $stmt2->fetch(PDO::FETCH_ASSOC);

        if ( $num_rows['user_id'] ){
            $_SESSION['error'] = 'all fine';

        } else {
            throw new \Exception('token is invalid');
        }

    $dbh_con->commit();

    header('Location: /b.php');
    exit();

} catch(PDOException $e) {

$dbh_con->rollBack();

$_SESSION['error'] = 'something is wrong';
header('Location: /b.php');
exit();
} catch(Exception $e) {

    $dbh_con->rollBack();

    $_SESSION['error'] = 'token is invalid';
    header('Location: /b.php');
    exit();
}
Comments