Les INSERT sont-ils automatiquement validés?

13

Notre application déclenche une requête INSERT dans la base de données MySQL pour ajouter des enregistrements. Je veux savoir si les enregistrements sont automatiquement validés. Si j'exécute la commande ROLLBACK, quand la base de données effectue-t-elle une restauration? Un ROLLBACK est-il possible après un COMMIT?

RPK
la source
Juste pour plus de précision, j'ai tagué comme 'innodb' il y a 19 heures, car InnoDB utilise COMMIT / ROLLBACK.
RolandoMySQLDBA
Cela obtient un +1 pour rappeler aux développeurs et aux administrateurs de bases de données de faire attention au comportement transactionnel, aux paradigmes d'application correspondants prenant en charge les transactions et à ses conséquences (bonnes ou mauvaises).
RolandoMySQLDBA
J'ai répondu à votre question avec un commentaire sous ma réponse.
RolandoMySQLDBA

Réponses:

10

La réponse à votre question dépend de si vous êtes ou non dans une transaction qui s'étalera sur plusieurs déclarations. (Vous avez marqué la question avec InnoDB, la réponse serait différente avec MyISAM.)

Depuis le manuel de référence: http://dev.mysql.com/doc/refman/5.1/en/commit.html

Par défaut, MySQL s'exécute avec le mode de validation automatique activé. Cela signifie que dès que vous exécutez une instruction qui met à jour (modifie) une table, MySQL stocke la mise à jour sur le disque pour la rendre permanente.

Donc oui, par défaut, si vous utilisez simplement INSERT, les enregistrements que vous insérez seront validés, et il est inutile d'essayer de les restaurer. (Cela revient en fait à encapsuler chaque instruction entre BEGINet COMMIT.)

Cependant, si vous traitez explicitement des transactions, vous devrez utiliser COMMITpour valider le stockage des enregistrements, mais vous pourrez également l'utiliser ROLLBACK.

Vous pouvez démarrer une transaction explicitement en utilisant START TRANSACTION(ou BEGIN). Ceci est indépendant du autocommitparamètre (activé par défaut):

Avec START TRANSACTION, la validation automatique reste désactivée jusqu'à ce que vous mettiez fin à la transaction avec COMMIT ou ROLLBACK. Le mode de validation automatique revient ensuite à son état précédent.

Alternativement, si autocommit=0, je pense que toute déclaration suivant une autre fin de transaction, démarrera une transaction (mais vous pouvez toujours l'utiliser START TRANSACTIONexplicitement); c'est du moins ainsi que j'interprète ceci :

Le mode de validation automatique. S'il est défini sur 1, toutes les modifications apportées à une table prennent effet immédiatement. S'il est défini sur 0, vous devez utiliser COMMIT pour accepter une transaction ou ROLLBACK pour l'annuler. Si la validation automatique est 0 et que vous la modifiez à 1, MySQL effectue un COMMIT automatique de toute transaction ouverte. Une autre façon de commencer une transaction consiste à utiliser une instruction START TRANSACTION ou BEGIN. Voir Section 12.3.1, «START TRANSACTION, COMMIT et ROLLBACK Syntax».

Plus précisément, "une autre façon de commencer une transaction" semble impliquer que la définition de "autocommit = 0" est suffisante pour démarrer une transaction (au moins juste avant chaque instruction au début d'une session ou qui suit un COMMIT/ ROLLBACK). Je suggérerais d'utiliser BEGINou START TRANSACTIONexplicitement de toute façon même si autocommit=0, car cela peut rendre plus clair de voir quand la transaction commence ou se termine.

(La façon dont vous démarrez une transaction peut dépendre de la façon dont votre application utilise MySQL.)

Bruno
la source
1
Mérite un +1 pour définir pleinement les protocoles transactionnels.
RolandoMySQLDBA
@Bruno, Pour MyISAM où "commit" et "rollback" ne fonctionnent pas, les insertions ne seraient-elles pas à moitié validées?
Pacerier
7

Par défaut, InnoDB est défini sur autocommit = 1 ou ON . Une fois engagés, ils ne peuvent pas être annulés .

Vous devrez faire l'une des deux choses pour le désactiver à l'avenir:

OPTION 1: Ajoutez ceci à /etc/my.cnf et redémarrez mysql

[mysqld]
autocommit=0

OPTION 2: effectuez l'une de ces opérations dans la base de données DB ouverte avant de commencer tout SQL significatif

SET autocommit = 0;
START TRANSACTION;

Sous ces deux options, vous devrez effectuer un COMMIT manuel ou un ROLLBACK manuel .

CAVEAT

Si le tableau est MyISAM, l'explication est plus simple. Comme il n'y a aucune transaction pour le moteur de stockage MyISAM, tous les INSERT, UPDATE et DELETE exécutés sont permanents. Aucun retour en arrière.

RolandoMySQLDBA
la source
Pour plus de précisions, ma réponse concerne les moteurs de stockage InnoDB et MyISAM.
RolandoMySQLDBA
1
Juste au cas où la validation automatique est désactivée dans InnoDB et que mon application lance des requêtes d'insertion et que j'oublie d'exécuter la validation, à quelle vitesse les modifications sont-elles perdues?
RPK
Si votre application déclenche manuellement un COMMIT après chaque INSERT, il est écrit et ne peut pas être supprimé. Si la connexion DB s'éteint avant de COMMIT, toutes les modifications sont perdues et la restauration se produit. Si vous effectuez une DDL (CREATE TABLE, DROP TABLE, ALTER TABLE, etc.) ou émettez manuellement un verrou de table, les INSERT sont automatiquement validés. Si vous utilisez START TRANSACTION, toutes les modifications non validées sont validées.
RolandoMySQLDBA
1
Concernant "Si vous utilisez START TRANSACTION, toutes les modifications non validées sont validées." (dans le contexte des DDL, sinon il serait annulé), il y a aussi un commit implicite avant (le commit implicite après est de la version 5.5.3 selon la documentation).
Bruno
1
"Si vous utilisez START TRANSACTION, toutes les modifications non validées sont validées." - J'ai eu cette idée dans MySQL 5.0 Certification Study Guide (ISBN 0-672-32812-7) Page 418 qui nomme START TRANSACTION, SET AUTOCOMMIT = 1, LOCK TABLES, UNLOCK TABLES, TRUNCATE TABLE, RENAME TABLE, DROP INDEX, DROP TABLE , DROP DATABASE, CREATE INDEX, BEGIN et ALTER TABLE sous les titres "Dans certaines circonstances, la transaction en cours peut se terminer implicitement: si vous émettez l'une des instructions suivantes, InnoDB valide implicitement les instructions non validées précédentes de la transaction en cours et commence un nouvelle transaction ".
RolandoMySQLDBA