Как я могу реализовать фиксацию/откат для MySQL в PHP?

StackOverflow https://stackoverflow.com/questions/329622

Вопрос

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

Вот мой базовый код (упрощенный для простоты):

$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, но не знаю, как это сделать.

Это было полезно?

Решение

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

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

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

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

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

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

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

Другие советы

Вам необходимо использовать таблицы на основе 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>";
    }
}
?>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top