1

使用 PDO,我试图在一个事务中运行两个准备好的语句。如果第一个成功执行,我只希望第二个准备好的语句运行,反之亦然。

//Open Database Connection
$dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pwd);

//Set Error Handling
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

//Run First Prepared Statement
$sql = 'UPDATE listers SET
        first_name = :first_name,
        last_name = :last_name,
        address = :address,
        apt = :apt,
        city = :city,
        state = :state,
        zip_1 = :zip_1,
        phone_prefix = :phone_prefix,
        phone_first = :phone_first,
        phone_last = :phone_last 
        WHERE lister_id = :lister_id';
try {   
    $dbh->beginTransaction();

    $result = $dbh->prepare($sql);
    $result->bindParam(':first_name', $_POST['first_name'], PDO::PARAM_STR); 
    $result->bindParam(':last_name', $_POST['last_name'], PDO::PARAM_STR); 
    $result->bindParam(':address', $_POST['address'], PDO::PARAM_STR);
    $result->bindParam(':apt', $_POST['apt'], PDO::PARAM_STR); 
    $result->bindParam(':city', $_POST['city'], PDO::PARAM_STR); 
    $result->bindParam(':state', $_POST['state'], PDO::PARAM_STR); 
    $result->bindParam(':zip_1', $_POST['zip_1'], PDO::PARAM_INT); 
    $result->bindParam(':phone_prefix', $phone_1_prefix, PDO::PARAM_INT); 
    $result->bindParam(':phone_first', $phone_1_first, PDO::PARAM_INT); 
    $result->bindParam(':phone_last', $phone_1_last, PDO::PARAM_INT);  
    $result->bindParam(':lister_id', $_GET['lister_id'], PDO::PARAM_INT); 

    $result->execute();


    //Run Second Prepared Statement
    $current_date = time(); //Current Date/time in Unix format

    $sql = 'INSERT INTO hidddstory_details SET
            history_id = :history_id, 
            listing_type = "lister",  
            date_added = :date_added,
            listing_id = :listing_id';

    $result = $dbh->prepare($sql);                                                    
    $result->bindParam(':history_id', $account_edited_admin, PDO::PARAM_INT);        
    $result->bindParam(':date_added', $current_date, PDO::PARAM_INT); 
    $result->bindParam(':listing_id', $row['lister_id'], PDO::PARAM_INT);                                  
    $result->execute();

    $dbh->commit();

} catch(PDOException $e) {
     $error = '<div id="error"><p class="error_message">The account could not be edited due to a system error. We apologize for any inconvenience.</p></div>';
     $dbh->rollBack();
     echo errorHandle($e);
}

当我在没有任何语法错误的情况下加载页面时,它会正确运行准备好的语句。当我故意在 history_details 表名中添加一些字母时,正如您在上面看到的那样,它会显示与不正确的表名相关的错误消息,这是应该的。不幸的是,它并没有回滚第一个准备好的语句,所以当我检查 listers 表时,它实际上已经更新了该表,它不应该这样做。

如何在事务中运行多个准备好的语句?

4

1 回答 1

3

检查您尝试对其执行事务的表的存储引擎,以确保它实际上支持事务。据我所知,InnoDB 是目前唯一支持事务的格式。不支持事务的引擎将默默地不做任何事情,不会发出错误,也不会进行任何回滚。

于 2013-08-05T03:13:41.490 回答