307 votes

Exemples de transactions PHP + MySQL

Je n'ai vraiment pas trouvé l'exemple normal du fichier PHP où les transactions MySQL sont utilisées. Pouvez-vous me montrer un exemple simple de cela?

Et une autre question. J'ai déjà fait beaucoup de programmation et n'ai pas utilisé de transactions. Puis-je mettre une fonction PHP ou quelque chose dans header.php que si un mysql_query échoue, alors les autres échouent aussi?


Je pense que je l'ai compris, est-ce exact?:

 mysql_query("SET AUTOCOMMIT=0");
mysql_query("START TRANSACTION");

$a1 = mysql_query("INSERT INTO rarara (l_id) VALUES('1')");
$a2 = mysql_query("INSERT INTO rarara (l_id) VALUES('2')");

if ($a1 and $a2) {
    mysql_query("COMMIT");
} else {        
    mysql_query("ROLLBACK");
}
 

342voto

Pascal MARTIN Points 195780

L'idée je l'utilise généralement lorsque l'on travaille avec des transactions ressemble à ceci (semi-pseudo-code):

try {
    // First of all, let's begin a transaction
    $db->beginTransaction();

    // A set of queries; if one fails, an exception should be thrown
    $db->query('first query');
    $db->query('second query');
    $db->query('third query');

    // If we arrive here, it means that no exception was thrown
    // i.e. no query has failed, and we can commit the transaction
    $db->commit();
} catch (Exception $e) {
    // An exception has been thrown
    // We must rollback the transaction
    $db->rollback();
}


Notez que, avec cette idée, si une requête échoue, une Exception doit être levée:

  • AOP peut le faire, en fonction de comment vous le configurer
  • autre chose, avec une autre API, vous pourriez avoir à tester le résultat de la fonction utilisée pour exécuter une requête, et de lever une exception de vous-même.


Malheureusement, il n'y a pas quelque chose de magique. Vous ne pouvez pas simplement mettre une instruction et des opérations se fait automatiquement: vous avez encore de spécifique et d'un groupe de requêtes doit être exécutée dans une transaction.

Par exemple, très souvent, vous aurez un couple de requêtes avant l'opération (avant l' begin) et un autre couple de requêtes après la transaction (après, soit commit ou rollback) et vous aurez envie de ces requêtes exécutées peu importe ce qui s'est passé (ou pas) dans la transaction.

116voto

good_evening Points 4262

Je pense que je l'ai compris, est-ce exact?:

 mysql_query("START TRANSACTION");

$a1 = mysql_query("INSERT INTO rarara (l_id) VALUES('1')");
$a2 = mysql_query("INSERT INTO rarara (l_id) VALUES('2')");

if ($a1 and $a2) {
    mysql_query("COMMIT");
} else {        
    mysql_query("ROLLBACK");
}
 

42voto

Gedzberg Alex Points 141
<?php
// trans.php
function begin()
{
mysql_query("BEGIN");
}

function commit()
{
mysql_query("COMMIT");
}

function rollback()
{
mysql_query("ROLLBACK");
}

mysql_connect("localhost","Dude1", "SuperSecret") or die(mysql_error());

mysql_select_db("bedrock") or die(mysql_error());

$query = "INSERT INTO employee (ssn,name,phone) values ('123-45-6789','Matt','1-800-555-1212')";

begin(); // transaction begins

$result = mysql_query($query);

if(!$result)
{
rollback(); // transaction rolls back
echo "transaction rolled back";
exit;
}
else
{
commit(); // transaction is committed
echo "Database transaction was successful";
}

?>

39voto

EleventyOne Points 1168

Comme c'est le premier résultat sur google pour "php mysql" opération, je pensais ajouter une réponse qui démontre explicitement comment faire cela avec mysqli (comme l'auteur original voulais des exemples). Voici un exemple simplifié de transactions avec PHP/mysqli:

// let's pretend that a user wants to create a new "group". we will do so
// while at the same time creating a "membership" for the group which
// consists solely of the user themselves (at first). accordingly, the group
// and membership records should be created together, or not at all.
// this sounds like a job for: TRANSACTIONS! (*cue music*)

$group_name = "The Thursday Thumpers";
$member_name = "EleventyOne";
$conn = new mysqli($db_host,$db_user,$db_passwd,$db_name); // error-check this

// note: this is meant for InnoDB tables. won't work with MyISAM tables.

try {

    $conn->autocommit(FALSE); // i.e., start transaction

    // assume that the TABLE groups has an auto_increment id field
    $query = "INSERT INTO groups (name) ";
    $query .= "VALUES ('$group_name')";
    $result = $conn->query($query);
    if ( !$result ) {
        $result->free();
        throw new Exception($conn->error);
    }

    $group_id = $conn->insert_id; // last auto_inc id from *this* connection

    $query = "INSERT INTO group_membership (group_id,name) ";
    $query .= "VALUES ('$group_id','$member_name')";
    $result = $conn->query($query);
    if ( !$result ) {
        $result->free();
        throw new Exception($conn->error);
    }

    // our SQL queries have been successful. commit them
    // and go back to non-transaction mode.

    $conn->commit();
    $conn->autocommit(TRUE); // i.e., end transaction
}
catch ( Exception $e ) {

    // before rolling back the transaction, you'd want
    // to make sure that the exception was db-related
    $conn->rollback(); 
    $conn->autocommit(TRUE); // i.e., end transaction   
}

Aussi, gardez à l'esprit que PHP 5.5 a une nouvelle méthode mysqli::begin_transaction. Toutefois, cela n'a pas été encore documentées par le PHP de l'équipe, et je suis toujours coincé dans PHP 5.3, donc je ne peux pas commenter.

11voto

dinesh Points 21

Veuillez vérifier quel moteur de stockage vous utilisez, si c'est MyISAM alors Transaction('COMMIT','ROLLBACK') ne sera pas supporté. Parce que le moteur de stockage innodb supporte les transactions pas MyISAM.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X