2010-04-19 3 views
2

Donc j'essaye d'effectuer quelques insertions à la fois qui sont un peu dépendantes les unes des autres. Disons que je fais un site Web de notation de chien. N'importe qui peut ajouter un chien à ma base de données, mais en faisant cela, il doit également ajouter une évaluation préliminaire du chien. D'autres personnes peuvent ensuite évaluer le chien après. Les chiens aux notes est une relation de plusieurs à un: un chien a de nombreuses cotes.Question codeigniter/mySQL. Vérifier si plusieurs insertions sont possibles avant l'insertion réelle

Cela signifie que pour mes additions préliminaires, puisque j'ai la personne à la fois évaluer et ajouter le chien, je dois prendre la note, et définir une clé étrangère à la clé primaire du chien. Pour autant que je sache, cela signifie que je dois effectivement ajouter le chien, puis vérifier la clé primaire de cette nouvelle addition, puis mettre cela dans mon classement avant l'insertion.

Maintenant, supposons que quelque chose se passe mal avec l'insertion de la note, que ce soit une chaîne trop longue ou quelque chose que j'ai oublié. Si la note a échoué, le chien a déjà été inséré, mais la note ne l'a pas été. Dans ce cas, j'aimerais que le chien n'ait pas été ajouté en premier lieu. Cela signifie-t-il que je dois écrire un code qui dit «si l'évaluation échoue, faire un retrait pour le chien» ou est-il un moyen de prédire quelle sera la clé pour le chien si tout se passe comme prévu. Existe-t-il un moyen de dire «tenir cet endroit», et si tout fonctionne, l'ajouter?

Toute aide serait grandement appréciée. Merci!!

Répondre

6

http://codeigniter.com/user_guide/database/transactions.html

REMARQUE:

MySQL, vous devrez être en cours d'exécution ou InnoDB types de table BDB plutôt que le MyISAM plus commun.

$this->db->trans_start(); 
$this->db->query('INSERT YOUR DOG'); 
$this->db->query('INSERT YOUR RATING'); 
$this->db->trans_complete(); 

if ($this->db->trans_status() === FALSE) 
{ 
    // Something went wrong, but nothing was committed to the database so you can handle the error here 
} 
else { 
    // Everything was added fine 
} 
+0

Cela ne fonctionne que s'il a le bon type de table (innoDb ... et ainsi de suite). – SeanJA

+0

Réponse éditée pour clarifier ce point. – Finbarr

+1

Alors question: Puis-je ne pas utiliser mes modèles si je vais le faire de cette façon? Je cours des insertions sur quelques tables différentes, mais toutes dans la même base de données. Puis-je faire quelque chose comme $ dog_db = $ this-> load-> base de données ('dog', true); $ dog_db-> trans_start(); if ($ $ this-> dog-> insert ($ dog)) $ dog_db-> trans_rollback(); sinon $ dog_db-> trans_commit(); – Ethan

3

Bienvenue sur le land of transactions! Je suis sûr que vous allez profiter de votre séjour, car les transactions ont été inventées spécialement pour ce problème. :)

Fondamentalement, la séquence des événements ressemblera à quelque chose comme ceci à MySQL:

START TRANSACTION; 
INSERT INTO dogs ...; 
INSERT INTO dog_ratings...; 
COMMIT; 

Maintenant, dans votre code, vous pouvez faire toutes sortes de choses entre ces requêtes, et mettre fin à la transaction à à tout moment en utilisant la requête SQL ROLLBACK. Lorsque vous faites cela, aucune des requêtes dans le cadre de votre transaction n'est stockée dans la base de données. Vous devrez faire CodeIgniter spécifique, mais au fond, il ressemblerait à quelque chose comme ceci:

$db->query("START TRANSACTION"); 
try { 
    $db->query("INSERT INTO dogs..."); 
    //did that work? Sweet. Run the next one. You can fetch the insert id 
    //here too, if you want to use it in the next query. 
    $db->query("INSERT INTO dog_ratings..."); 
    $db->query("COMMIT"); 
} 
catch (DatabaseException $e) 
{ 
    $db->query("ROLLBACK"); 
    echo "Problem! ".$e->getMessage(); 
} 

Dans le code ci-dessus, en supposant que $db est une sorte d'objet wrapper de base de données qui jetteront un DatabaseException lorsqu'une requête échoue , puis aucun enregistrement ne sera créé si un problème est rencontré avec l'une des requêtes dans la transaction.

Il y a beaucoup à apprendre sur les transactions, donc google autour d'un peu. La principale chose à noter est qu'avec MySQL, vous devez utiliser des tables InnoDB pour supporter les transactions. Si vous utilisez MyISAM, des commandes telles que START TRANSACTION et COMMIT seront exécutées, mais elles ne font rien. CodeIgniter simplifie ce processus en utilisant des transactions.

+0

BDB est également transaction en toute sécurité – SeanJA

+0

muchas gracias, zombat! – Ethan

Questions connexes