【问题标题】:Proper usage of php mysqli autocommit and rollback正确使用 php mysqli 自动提交和回滚
【发布时间】:2014-01-22 05:45:51
【问题描述】:

在正确使用 mysqli 自动提交时遇到问题。以下是查询。

Table1 和 Table3 是 InnoDB 而 Table2 是 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()?

【问题讨论】:

    标签: php mysql mysqli


    【解决方案1】:

    当您有一系列 sql 语句必须一起执行以保持数据库的一致性时,您可以使用它。将调用 commit 视为在游戏中建立一个保存点。每当您调用回滚时,您都会撤消上一次提交之前所做的所有事情。

    假设您需要将发票保存在您的发票表中,将详细信息保存在您的 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");
    }
    

    【讨论】:

    • 现在我明白了。所以commit 完成并rollback 很好地回滚事务。自动提交参数true 和false 呢?手册上说Whether to turn on auto-commit or not. 所以通过设置 false 我将其关闭?
    • 没错。可能最好的解决方案是将其保持打开状态,仅在需要时才关闭。此外,使用transaction 可能更有意义,因此您不必怀疑自动提交设置的值。
    • 当我在 PHP 文档中作为评论阅读它时,打开和关闭自动提交也会提交尚未提交的所有内容。那么我可以再次打开它而不是提交吗? $dbconnect->autocommit(true) 在try 的末尾
    • 可能不是最好的主意。鉴于该行为未记录在案,未来版本可能会发生变化。
    • 所以commit然后再打开autocommit(true)更好?
    猜你喜欢
    • 2012-09-17
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多