web-dev-qa-db-fra.com

Différence entre SET autocommit = 1 et START TRANSACTION dans mysql (Ai-je oublié quelque chose?)

Je lis sur les transactions dans MySQL et je ne sais pas si j'ai bien saisi quelque chose de spécifique, et je veux être sûr d'avoir bien compris, alors voici. Je sais ce qu'une transaction est censée faire, je ne suis simplement pas sûr d'avoir compris la sémantique de l'instruction ou non.

Donc, ma question est, est-ce que quelque chose ne va pas (et, si c'est le cas, qu'est-ce qui ne va pas) avec ce qui suit:

Par défaut, le mode de validation automatique est activé dans MySQL.

À présent, SET autocommit=0; commencera une transaction, SET autocommit=1; sera implicitement validé. Il est possible de COMMIT; aussi bien que ROLLBACK;, dans les deux cas, l'autocommit est toujours défini sur 0 par la suite (et une nouvelle transaction est implicitement démarrée).

START TRANSACTION; sera essentiellement SET autocommit=0; jusqu'à ce qu'un COMMIT; ou ROLLBACK; se déroule.

En d'autres termes, START TRANSACTION; et SET autocommit=0; sont équivalents, sauf que START TRANSACTION; fait l'équivalent d'ajouter implicitement un SET autocommit=0; après COMMIT; ou ROLLBACK;

Si tel est le cas, je ne comprends pas http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html#isolevel_serializable - vu comme ayant un niveau d'isolement implique qu'il y a une transaction, ce qui signifie que la validation automatique devrait être désactivée de toute façon?

Et s'il y a une autre différence (autre que celle décrite ci-dessus) entre le début d'une transaction et la configuration de l'autocommit, qu'est-ce que c'est?

65
ralokt

La connaissance de la gestion des transactions (autocommit, explicites et implicites) pour votre base de données peut vous éviter d'avoir à restaurer des données à partir d'une sauvegarde.

Les transactions contrôlent les instructions de manipulation des données pour s'assurer qu'elles sont atomiques. Être "atomique" signifie que la transaction se produit ou non. La seule façon de signaler l'achèvement de la transaction à la base de données est d'utiliser une instruction COMMIT ou ROLLBACK (selon ANSI-92, qui malheureusement n'a pas inclus de syntaxe pour créer/commencer une transaction afin il est spécifique au fournisseur). COMMIT applique les modifications (le cas échéant) apportées dans la transaction. ROLLBACK ignore toutes les actions qui ont eu lieu dans la transaction - hautement souhaitable quand une instruction UPDATE/DELETE fait quelque chose de involontaire .

En règle générale, les instructions DML (Insert, Update, Delete) individuelles sont exécutées dans une transaction de validation automatique - elles sont validées dès que l'instruction se termine avec succès. Ce qui signifie qu'il n'y a aucune possibilité de restaurer la base de données à l'état avant l'exécution de l'instruction dans des cas comme le vôtre. En cas de problème, la seule option de restauration disponible consiste à reconstruire les données à partir d'une sauvegarde (à condition qu'il en existe une). Dans MySQL, la validation automatique est on par défaut pour InnoDB - MyISAM ne prend pas en charge transactions. Il peut être désactivé en utilisant:

SET autocommit = 0

Une transaction explicite est lorsque les instructions sont enveloppées dans un bloc de code de transaction défini explicitement - pour MySQL, c'est START TRANSACTION . Il requiert également une instruction COMMIT ou ROLLBACK explicitement créée à la fin de la transaction. Les transactions imbriquées dépassent le cadre de cette rubrique.

Les transactions implicites sont légèrement différentes des transactions explicites. Les transactions implicites ne nécessitent pas de définir explicitement une transaction. Cependant, comme les transactions explicites, elles nécessitent la fourniture d'une instruction COMMIT ou ROLLBACK.

Conclusion

Les transactions explicites sont la solution la plus idéale - elles nécessitent une instruction, COMMIT ou ROLLBACK, pour finaliser la transaction, et ce qui se passe est clairement indiqué pour que d'autres puissent le lire en cas de besoin. Les transactions implicites sont correctes si vous travaillez avec la base de données de manière interactive, mais les instructions COMMIT ne doivent être spécifiées qu'une fois les résultats testés et soigneusement déterminés pour être valides.

Cela signifie que vous devez utiliser:

SET autocommit = 0;

START TRANSACTION;
  UPDATE ...;

... et utilisez uniquement COMMIT; lorsque les résultats sont corrects.

Cela dit, les instructions UPDATE et DELETE ne renvoient généralement que le nombre de lignes concernées, et non des détails spécifiques. Convertissez ces instructions en instructions SELECT et examinez les résultats pour garantir leur exactitude prior pour tenter l'instruction UPDATE/DELETE.

Addenda

Les instructions DDL (Data Definition Language) sont automatiquement validées - elles ne nécessitent pas d'instruction COMMIT. IE: Table, index, procédure stockée, base de données et instructions de création ou de modification de vue.

64
OMG Ponies

Dans InnoDB vous avez START TRANSACTION;, qui dans ce moteur est la méthode officiellement recommandée pour effectuer des transactions, au lieu de SET AUTOCOMMIT = 0; (n'utilisez pas SET AUTOCOMMIT = 0; pour les transactions dans InnoDB sauf s'il s'agit d'optimiser lecture seule transactions). Validez avec COMMIT;.

Vous voudrez peut-être utiliser SET AUTOCOMMIT = 0; in InnoDB à des fins de test, et pas précisément pour les transactions.

Dans MyISAM vous n'avez pas START TRANSACTION;. Dans ce moteur, utilisez SET AUTOCOMMIT = 0; pour les transactions. Validez avec COMMIT; ou SET AUTOCOMMIT = 1; (Différence expliquée dans l'exemple de commentaire MyISAM ci-dessous). Vous pouvez également effectuer des transactions de cette manière dans InnoDB.

Source: http://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_autocommit

Exemples de transactions à usage général:

/* InnoDB */
START TRANSACTION;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

COMMIT; /* SET AUTOCOMMIT = 1 might not set AUTOCOMMIT to its previous state */

/* MyISAM */
SET AUTOCOMMIT = 0;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

SET AUTOCOMMIT = 1; /* COMMIT statement instead would not restore AUTOCOMMIT to 1 */
18
mikl

Si vous souhaitez utiliser la restauration, utilisez alors start transaction et sinon oubliez toutes ces choses, car MySQL définit autocommit sur 1 par défaut.

2
RINSON KE