web-dev-qa-db-fra.com

Annulation automatique si COMMIT TRANSACTION n'est pas atteinte

Considérer ce qui suit:

START TRANSACTION;

BEGIN;

INSERT INTO prp_property1 (module_name,environment_name,NAME,VALUE) VALUES ('','production','','300000');

/** Assume there is syntax error SQL here...**/
Blah blah blah

DELETE FROM prp_property1 WHERE environment_name = 'production';

COMMIT TRANSACTION;

Question:

J'ai remarqué que la transaction est automatiquement annulée et que la tentative d'insertion d'enregistrement échoue.

Si je ne fournis pas de gestionnaire d'erreurs ni de contrôle d'erreurs avec ROLLBACK TRANSACTION comme ci-dessus, est-il prudent, car il semble que le travail soit exécuté dans un exemple comme ci-dessus, car le COMMIT TRANSACTION n'est jamais exécuté?

Je suppose que la transaction est immédiatement annulée et rejetée dès qu'une erreur se produit.

16
Koekiebox

Non, les transactions ne sont pas annulées dès qu'une erreur survient. Mais vous utilisez peut-être une application cliente qui applique cette stratégie. 

Par exemple, si vous utilisez le client en ligne de commande mysql, celui-ci cesse normalement de s'exécuter lorsqu'une erreur se produit et se ferme. Si vous quittez une transaction en cours, celle-ci est annulée.

Lorsque vous écrivez votre propre application, vous pouvez contrôler la stratégie lors de la restauration, à quelques exceptions près:

  • La fermeture (c’est-à-dire la déconnexion de la base de données) annule toujours une transaction en cours.
  • Un blocage ou un délai d'attente de verrouillage entraîne implicitement une restauration

En dehors de ces conditions, si vous appelez une commande générant une erreur, celle-ci est renvoyée normalement et vous êtes libre de faire ce que vous voulez, y compris de toute façon engager la transaction.

22
MarkR

Vous pouvez utiliser procedure pour le faire plus efficacement.
Transaction avec procédure stockée sur le serveur MySQL

8
tech_me

Utiliser la procédure stockée Mysql

   BEGIN

   DECLARE exit handler for sqlexception
      BEGIN
      ROLLBACK;
   END;

   DECLARE exit handler for sqlwarning
     BEGIN
     ROLLBACK;
   END;

   START TRANSACTION;

   INSERT INTO prp_property1 (module_name,environment_name,NAME,VALUE) VALUES ('','production','','300000');

   [ERROR]

   COMMIT;

   END

Vous pouvez définir si l'avertissement ou l'annulation d'une erreur, vous n'avez pas besoin de supprimer, avec la transaction toute l'entrée est supprimée.

5

J'aimerais ajouter à ce que @MarkR a déjà dit. La gestion des erreurs, en supposant que le moteur InnoDB, se déroule comme décrit dans Mysql Server Documentation

  • Si vous manquez d'espace fichier dans un tablespace, une erreur est générée dans la table MySQL et InnoDB annule l'instruction SQL.
  • Un blocage de transaction amène InnoDB à annuler l'intégralité de la transaction.
  • Une erreur de clé en double annule l'instruction SQL
  • Une erreur de ligne trop longue annule l'instruction SQL.
  • Les autres erreurs sont principalement détectées par la couche de code MySQL (au-dessus du niveau du moteur de stockage InnoDB) et annulent l’instruction SQL correspondante.

Je crois comprendre également que lorsque la session Mysql se termine (à la fin des scripts php), tout ce qui n’est pas validé est annulé. Je dois encore trouver une source vraiment fiable pour soutenir cette déclaration, alors ne prenez pas ma parole pour elle.

4
Nicola Pedretti

J'ai testé ces trois situations. MySQL ne s'installe pas automatiquement.

Un blocage de transaction entraîne l'annulation par InnoDB de la totalité de la transaction. Une erreur de clé en double annule l'instruction SQL Une erreur de ligne trop longue annule l'instruction SQL.

Seuls les enregistrements affectés échouent, les autres enregistrements réussissent sauf si votre application appelle explicitement "annulation".

0
Wen