Gli INSERT si impegnano automaticamente?


13

La nostra applicazione genera una query INSERT nel database MySQL per aggiungere record. Voglio sapere se i record vengono impegnati automaticamente. Se eseguo il comando ROLLBACK, quando viene eseguito il rollback del database? Un ROLLBACK è possibile dopo un COMMIT?


Solo per chiarimenti, ho taggato come "innodb" 19 ore fa, poiché InnoDB utilizza COMMIT / ROLLBACK.
RolandoMySQLDBA,

Questo ottiene un +1 per ricordare agli sviluppatori e ai DBA di prestare attenzione al comportamento transazionale, ai paradigmi applicativi corrispondenti che supportano le transazioni e alle sue conseguenze (buone o cattive).
RolandoMySQLDBA,

Ho risposto alla tua domanda con un commento sotto la mia risposta.
RolandoMySQLDBA il

Risposte:


10

La risposta alla tua domanda dipende dal fatto che tu sia o meno all'interno di una transazione che si estenderà su più di una dichiarazione. (Hai taggato la domanda con InnoDB, la risposta sarebbe diversa con MyISAM.)

Dal manuale di riferimento: http://dev.mysql.com/doc/refman/5.1/en/commit.html

Per impostazione predefinita, MySQL funziona con la modalità autocommit abilitata. Ciò significa che non appena si esegue un'istruzione che aggiorna (modifica) una tabella, MySQL memorizza l'aggiornamento su disco per renderlo permanente.

Quindi sì, per impostazione predefinita, se stai solo usando INSERT, i record che inserisci saranno sottoposti a commit e non ha senso provare a ripristinarli. (Questo è effettivamente lo stesso che avvolge ogni istruzione tra BEGINe COMMIT.)

Tuttavia, se hai a che fare con transazioni esplicite, dovrai utilizzare COMMITper eseguire l'archiviazione dei record, ma sarai anche in grado di utilizzare ROLLBACK.

È possibile avviare una transazione in modo esplicito utilizzando START TRANSACTION(o BEGIN). Questo è indipendente autocommitdall'impostazione (attivata per impostazione predefinita):

Con START TRANSACTION, autocommit rimane disabilitato fino al termine della transazione con COMMIT o ROLLBACK. La modalità autocommit torna quindi al suo stato precedente.

In alternativa, se autocommit=0, penso che qualsiasi dichiarazione che segue un'altra fine della transazione, avvierà una transazione (ma puoi comunque utilizzarla START TRANSACTIONesplicitamente); questo è almeno il modo in cui lo interpreto :

La modalità autocommit. Se impostato su 1, tutte le modifiche a una tabella hanno effetto immediato. Se impostato su 0, è necessario utilizzare COMMIT per accettare una transazione o ROLLBACK per annullarla. Se autocommit è 0 e lo si modifica in 1, MySQL esegue un COMMIT automatico per qualsiasi transazione aperta. Un altro modo per iniziare una transazione è usare un'istruzione START TRANSACTION o BEGIN. Vedere la Sezione 12.3.1, "INIZIA TRANSAZIONE, COMMIT e sintassi ROLLBACK".

Più specificamente "un altro modo per iniziare una transazione" sembra implicare che l'impostazione "autocommit = 0" è sufficiente per avviare una transazione (almeno appena prima di ogni istruzione all'inizio di una sessione o che segue un COMMIT/ ROLLBACK). Suggerirei di utilizzare esplicitamente BEGINo START TRANSACTIONcomunque anche se autocommit=0, in quanto può rendere più chiaro vedere quando inizia o termina la transazione.

(Il modo in cui si avvia una transazione può dipendere dal modo in cui l'applicazione utilizza MySQL.)


1
Merita un +1 per la definizione completa dei protocolli transazionali.
RolandoMySQLDBA il

@Bruno, per MyISAM in cui "commit" e "rollback" non funzionano, gli inserti non sarebbero impegnati a metà?
Pacerier,

7

Per impostazione predefinita, InnoDB è impostato su autocommit = 1 o ON . Una volta impegnati, non possono essere ripristinati .

Dovresti fare una delle due cose per disabilitarlo in futuro:

OPZIONE 1: aggiungi questo a /etc/my.cnf e riavvia mysql

[mysqld]
autocommit=0

OPZIONE 2: eseguire uno di questi nella Conenction DB aperta prima di iniziare qualsiasi SQL significativo

SET autocommit = 0;
START TRANSACTION;

Con queste due opzioni, dovresti eseguire un COMMIT manuale o un ROLLBACK manuale .

AVVERTIMENTO

Se la tabella è MyISAM, la spiegazione è più semplice. Poiché non vi sono transazioni per il motore di archiviazione MyISAM, tutti gli INSERT, gli UPDATE e i DELETE eseguiti sono permanenti. Nessun rollback di sorta.


Per ulteriori chiarimenti, la mia risposta riguarda sia i motori di archiviazione InnoDB che MyISAM.
RolandoMySQLDBA,

1
Nel caso in cui Auto Commit sia disattivato in InnoDB e la mia applicazione stia eseguendo Inserisci query e dimentico di eseguire Commit, quanto tempo vengono perse le modifiche?
RPK,

Se l'applicazione attiva manualmente un COMMIT dopo ogni INSERT, viene scritta e non può essere eliminata. Se la connessione DB si interrompe prima di COMMIT, tutte le modifiche vengono perse e si verifica il rollback. Se si esegue un DDL (CREATE TABLE, DROP TABLE, ALTER TABLE, ecc.) O si emette manualmente un blocco tabella, gli INSERT vengono inseriti automaticamente. Se si utilizza INIZIA TRANSAZIONE, vengono eseguite tutte le modifiche non impegnate.
RolandoMySQLDBA il

1
Riguardo a "Se usi START TRANSACTION, tutte le modifiche non confermate vengono confermate." (nel contesto dei DDL, altrimenti verrebbe eseguito il rollback), c'è anche un commit implicito prima (il commit implicito dopo è dalla versione 5.5.3 secondo la documentazione).
Bruno,

1
"Se si utilizza INIZIA TRANSAZIONE, vengono eseguite tutte le modifiche non impegnate." - L'idea mi è venuta da MySQL 5.0 Guida allo studio di certificazione (ISBN 0-672-32812-7) Pagina 418 che chiama START TRANSACTION, SET AUTOCOMMIT = 1, LOCK TABLES, UNLOCK TABLES, TRUNCATE TABLE, RENAME TABLE, DROP INDEX, DROP TABLE , DROP DATABASE, CREATE INDEX, INIZIA e ALTER TABLE sotto i titoli "In alcune circostanze, la transazione corrente potrebbe terminare implicitamente: Se si emette una delle seguenti dichiarazioni, InnoDB impegna implicitamente le precedenti dichiarazioni non confermate della transazione corrente e inizia un nuova transazione ".
RolandoMySQLDBA il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.