正确使用php mysqli autocommit和rollback

时间:2014-01-22 05:45:51

标签: php mysql mysqli

正确使用mysqli autocommit时遇到问题。以下是查询。

表1和表3是InnoDB,而表2是MyISAM

正确插入表2和表3的值,但未存储表1的值。 运行代码时不会发生错误。

$dbconnect->autocommit(false);

$stmt = $dbconnect->prepare("INSERT INTO `table1`(`col1`,`col2`) VALUES (?,?)");
$stmt->bind_param('ss',$val1,$val2);
$stmt->execute();
$dbconnect->rollback();

$stmt = $dbconnect->prepare("INSERT INTO `table2`(`col1`,`col2`) VALUES (?,?)");
$stmt->bind_param('ss',$val3,$val4);
$stmt->execute();
$dbconnect->rollback();

$stmt = $dbconnect->prepare("INSERT INTO `table3`(`col1`,`col2`) VALUES (?,?)");
$stmt->bind_param('ss',$val5,$val6);
$stmt->execute();

$dbconnect->commit();

何时以及如何使用autocommit(false)和rollback()?

1 个答案:

答案 0 :(得分:7)

当您拥有一系列必须一起执行的sql语句以保持数据库的一致性时,可以使用它。考虑将提交称为在游戏中建立保存点。无论何时调用回滚,都可以撤消在上一次提交之前完成的所有操作。

想象一下,您需要在发票表中保存发票,invoice_details表中的详细信息以及付款表中的付款。为了保持一致性,您需要确保这些都已完成或者没有完成。如果您在哪里添加发票和详细信息,然后插入付款失败,那么您的数据库将处于不一致状态。

通常这是使用try / catch块完成的,如下所示:

try {
    $dbconnect->autocommit(false);

    $stmt = $dbconnect->prepare("INSERT INTO `invoices`(`col1`,`col2`) VALUES (?,?)");
    $stmt->bind_param('ss',$val1,$val2);
    $stmt->execute();

    $stmt = $dbconnect->prepare("INSERT INTO `invoice_details`(`col1`,`col2`) VALUES (?,?)");
    $stmt->bind_param('ss',$val3,$val4);
    $stmt->execute();

    $stmt = $dbconnect->prepare("INSERT INTO `payments`(`col1`,`col2`) VALUES (?,?)");
    $stmt->bind_param('ss',$val5,$val6);
    $stmt->execute();

    $dbconnect->commit();
} catch(Exception $e){
    // undo everything that was done in the try block in the case of a failure.
    $dbconnect->rollback();

    // throw another exception to inform the caller that the insert group failed.
    throw new StorageException("I couldn't save the invoice");
}