Pergunta

Bem, basicamente eu tenho esse script que leva um longo tempo para executar e, ocasionalmente vezes para fora e folhas de dados semi-completos flutuando em volta do meu banco de dados. (Sim, eu sei, em um mundo perfeito eu corrigir isso em vez de implementar commits e rollbacks mas sou forçado a não fazer isso)

Aqui está o meu código básico (suavizado pela simplicidade):

$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;

Então, o meu problema é que, se que, se todo o processo dentro desse loop while não é completa, então eu não quero a linha inserida para permanecer lá. Eu acho que de alguma forma eu poderia usar commits / reversões no início e no final do loop while para fazer isso, mas não sei como.

Foi útil?

Solução

Dê uma olhada este tutorial sobre transações com DOP.

Basicamente embrulhar o código de longa duração em:

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

de acordo com esta página do documento DOP :

"Quando as extremidades de script ou quando uma conexão está prestes a ser fechado, se você tem uma transação pendente, DOP vai rolar automaticamente para trás."

Então, você vai perder a transação que estava pendente quando o script expirou.

Mas, realmente, você deve redesenhar isso para que ele não depende do scriipt permanecer vivo.

Outras dicas

Você precisa usar tabelas com base InnoDB para transações, em seguida, usar qualquer biblioteca como DOP ou MySQLi que apoia-los.

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>";
    }
}
?>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top