Как я могу реализовать commit / rollback для MySQL в PHP?

ну в основном у меня есть этот скрипт, который занимает много времени для выполнения и иногда тайм-аут и оставляет полупустые данные, плавающие вокруг моей базы данных. (Да, я знаю, что в идеальном мире я бы исправил это вместо реализации коммитов и откатов, но я вынужден не делать этого)

вот мой основной код (dumbed вниз для простоты):

$database = new PDO("mysql:host=host;dbname=mysql_db","username","password");

while (notDone())
{
    $add_row = $database->prepare("INSERT INTO table (columns) VALUES (?)");
    $add_row->execute(array('values'));

    //PROCESSING STUFF THAT TAKES A LONG TIME GOES HERE
}

$database = null;

Итак, моя проблема в том, что если это, если весь процесс в этом цикле while не завершен, то я не хочу строка вставлена, чтобы остаться там. Я думаю, что каким-то образом я мог бы использовать коммиты/откаты в начале и конце цикла while, чтобы сделать это, но не знаю, как.

4 ответов


посмотри в этом уроке о транзакциях с PDO.

в основном оберните длинный рабочий код в:

$dbh->beginTransaction();
...
$dbh->commit();

и согласно этой странице документа PDO:

" когда скрипт заканчивается или когда соединение будет закрыто, если у вас есть незавершенная транзакция, PDO автоматически откатит ее. "

таким образом, Вы потеряете транзакцию, которая ожидала, когда сценарий приурочен из.

но на самом деле, вы должны перепроектировать это так, чтобы это не зависело от того, что scriipt останется в живых.


вам нужно использовать таблицы на основе InnoDB для транзакций, а затем использовать любую библиотеку, такую как PDO или MySQLi, которая их поддерживает.


try
{
    $mysqli->autocommit(FALSE);
    $mysqli->query("insert into tblbook (id,cid,book) values('','3','book3.1')");
    echo $q_ins=$mysqli->affected_rows."<br>";
    $mysqli->query("update tblbook set book='book3' where cid='3'");
    echo $q_upd=$mysqli->affected_rows."<br>";
    $mysqli->commit();
}
catch(PDOException $e)
{
    $mysqli->rollback();
    echo $sql . '<br />' . $e->getMessage();
}

<?php
//This may help someone....This code commit the transactions
//only if both queries insert and update successfully runs

$mysqli=new mysqli("localhost","user_name","password","db_name");

if(mysqli_connect_errno())
{
    echo "Connection failed: ".mysqli_connect_error();
}
else
{
    $mysqli->autocommit(FALSE);
    $mysqli->query("insert into tblbook (id,cid,book) values('','3','book3.1')");
    echo $q_ins=$mysqli->affected_rows."<br>";
    $mysqli->query("update tblbook set book='book3' where cid='3'");
    echo $q_upd=$mysqli->affected_rows."<br>";

    if($q_ins==1 && $q_upd==1)
    {
        $mysqli->commit();
        echo "Commit<br>";
    }
    else
    {
        $mysqli->rollback();
        echo "Rollback<br>";
    }
}
?>