Os INSERTs são confirmados automaticamente?

13

Nosso aplicativo dispara uma consulta INSERT no banco de dados MySQL para adicionar registros. Quero saber se os registros são ou não confirmados automaticamente. Se eu executar o comando ROLLBACK, quando o banco de dados executa uma reversão? É possível um ROLLBACK após um COMMIT?

RPK
fonte
Apenas para esclarecimento, eu marquei como 'innodb' 19 horas atrás, já que o InnoDB usa COMMIT / ROLLBACK.
RolandoMySQLDBA
Isso recebe +1 para lembrar aos desenvolvedores e DBAs que prestem atenção ao comportamento transacional, aos paradigmas de aplicativos que corroboram o suporte às transações e suas conseqüências (boas ou ruins).
RolandoMySQLDBA
Respondi sua pergunta com um comentário em minha resposta.
RolandoMySQLDBA

Respostas:

10

A resposta para sua pergunta depende se você está ou não em uma transação que abrange mais de uma declaração. (Você marcou a pergunta no InnoDB, a resposta seria diferente no MyISAM.)

No manual de referência: http://dev.mysql.com/doc/refman/5.1/en/commit.html

Por padrão, o MySQL é executado com o modo de confirmação automática ativado. Isso significa que, assim que você executa uma instrução que atualiza (modifica) uma tabela, o MySQL armazena a atualização no disco para torná-la permanente.

Portanto, sim, por padrão, se você estiver apenas usando INSERT, os registros inseridos serão confirmados e não há sentido em tentar revertê-los. (Isso é efetivamente o mesmo que agrupar cada instrução entre BEGINe COMMIT.)

No entanto, se você estiver lidando com transações explicitamente, precisará usar COMMITpara confirmar o armazenamento dos registros, mas também poderá usá-lo ROLLBACK.

Você pode iniciar uma transação explicitamente usando START TRANSACTION(ou BEGIN). Isso é independente da autocommitconfiguração (ativada por padrão):

Com START TRANSACTION, a confirmação automática permanece desativada até você finalizar a transação com COMMIT ou ROLLBACK. O modo de confirmação automática é revertido para o estado anterior.

Como alternativa, se autocommit=0eu acho que qualquer declaração após outro final de transação iniciará uma transação (mas você ainda pode usar START TRANSACTIONexplicitamente); é pelo menos assim que interpreto isso :

O modo de confirmação automática. Se definido como 1, todas as alterações em uma tabela entram em vigor imediatamente. Se definido como 0, você deve usar COMMIT para aceitar uma transação ou ROLLBACK para cancelá-la. Se a confirmação automática for 0 e você a alterar para 1, o MySQL executará um COMMIT automático de qualquer transação aberta. Outra maneira de iniciar uma transação é usar uma instrução START TRANSACTION ou BEGIN. Consulte a Seção 12.3.1, “Sintaxe START TRANSACTION, COMMIT e ROLLBACK”.

Mais especificamente, "outra maneira de iniciar uma transação" parece implicar que a configuração "confirmação automática = 0" é suficiente para iniciar uma transação (pelo menos antes de cada instrução no início de uma sessão ou que segue um COMMIT/ ROLLBACK). Eu sugeriria usar BEGINou START TRANSACTIONexplicitamente de qualquer maneira, mesmo que autocommit=0, pois pode ficar mais claro para ver quando a transação inicia ou termina.

(Como você inicia uma transação pode depender da maneira como seu aplicativo usa o MySQL.)

Bruno
fonte
1
Merece um +1 para definir totalmente os protocolos transacionais.
RolandoMySQLDBA
@Bruno, para o MyISAM onde "commit" e "rollback" não funcionam, as inserções não seriam confirmadas pela metade?
Pacerier
7

Por padrão, o InnoDB está definido como confirmação automática = 1 ou LIGADO . Uma vez confirmados, eles não podem ser revertidos .

Você precisaria fazer uma de duas coisas para desativá-lo daqui para frente:

OPÇÃO 1: Adicione isso ao /etc/my.cnf e reinicie o mysql

[mysqld]
autocommit=0

OPÇÃO 2: Execute um destes no DB Conenction aberto antes de iniciar qualquer SQL significativo

SET autocommit = 0;
START TRANSACTION;

Sob essas duas opções, você precisaria executar um COMMIT manual ou um ROLLBACK manual .

EMBARGO

Se a tabela for MyISAM, a explicação é mais simples. Como não há transações para o mecanismo de armazenamento MyISAM, todos os INSERTs, UPDATEs e DELETEs executados são permanentes. Nenhuma reversão.

RolandoMySQLDBA
fonte
Para esclarecimentos adicionais, minha resposta aborda os mecanismos de armazenamento InnoDB e MyISAM.
RolandoMySQLDBA
1
Caso o Auto Commit esteja desativado no InnoDB e meu aplicativo esteja disparando Insert Queries, e eu esqueço de executá-lo, em quanto tempo as alterações são perdidas?
RPK
Se seu aplicativo acionar manualmente um COMMIT após cada INSERT, ele será gravado e não poderá ser excluído. Se a conexão com o banco de dados morrer antes de você se confirmar, todas as alterações serão perdidas e ocorrerá a reversão. Se você executar qualquer DDL (CREATE TABLE, DROP TABLE, ALTER TABLE, etc.) ou emitir manualmente um bloqueio de tabela, os INSERTs serão automaticamente autorizados. Se você usar START TRANSACTION, todas as alterações não confirmadas serão confirmadas.
RolandoMySQLDBA
1
Em relação a "Se você usar START TRANSACTION, todas as alterações não confirmadas serão confirmadas". (no contexto de DDLs, caso contrário, seria revertida), também há uma confirmação implícita antes (a confirmação implícita depois é da versão 5.5.3, de acordo com a documentação).
Bruno
1
"Se você usar START TRANSACTION, todas as alterações não confirmadas serão confirmadas." - Tive essa idéia do MySQL 5.0 - Guia de Estudo de Certificação (ISBN 0-672-32812-7) Página 418, que nomeia INICIAR TRANSAÇÃO, CONFIGURAR AUTOCOMMIT = 1, TABELAS DE BLOQUEIO, TABELAS DE DESBLOQUEIO, TABELA DE TRUNCATE, TABELA DE RENOMEAMENTO, ÍNDICE DE QUEDA, TABELA DE QUEDA , DROP DATABASE, CREATE INDEX, BEGIN e ALTER TABLE sob os títulos "Em algumas circunstâncias, a transação atual pode terminar implicitamente: Se você emitir qualquer uma das seguintes instruções, o InnoDB comprometerá implicitamente as instruções não confirmadas anteriores da transação atual e inicia um nova transação ".
RolandoMySQLDBA