Pregunta

Bueno, básicamente tengo este script que lleva mucho tiempo ejecutarlo y ocasionalmente agota el tiempo y deja datos semi-completos flotando alrededor de mi base de datos. (Sí, sé que en un mundo perfecto arreglaría ESO en lugar de implementar commits y rollback, pero me veo obligado a no hacerlo)

Aquí está mi código básico (simplificado):

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

Entonces, mi problema es que si eso si todo el proceso dentro de ese ciclo while no está completo, entonces no quiero que la fila insertada permanezca allí. Creo que de alguna manera podría usar commits / rollbacks al principio y al final del ciclo while para hacer esto, pero no sé cómo.

¿Fue útil?

Solución

Eche un vistazo a este tutorial sobre transacciones con DOP.

Básicamente, envuelva el código de larga ejecución en:

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

Y según esta página del documento PDO :

" Cuando finaliza el script o cuando una conexión está por cerrarse, si tiene una transacción pendiente, PDO la revertirá automáticamente. "

Entonces perderá la transacción que estaba pendiente cuando se agotó el tiempo de espera del script.

Pero en realidad, deberías rediseñar esto para que no dependa de que el scriipt se mantenga vivo.

Otros consejos

Debe usar tablas basadas en InnoDB para las transacciones y luego usar cualquier biblioteca como PDO o MySQLi que las admita.

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top