Estou trabalhando em um programa que emite DDL. Eu gostaria de saber se CREATE TABLE
um DDL semelhante pode ser revertido em
- Postgres
- MySQL
- SQLite
- et al
Descreva como cada banco de dados lida com transações com DDL.
Estou trabalhando em um programa que emite DDL. Eu gostaria de saber se CREATE TABLE
um DDL semelhante pode ser revertido em
Descreva como cada banco de dados lida com transações com DDL.
Respostas:
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis fornece uma visão geral desse problema da perspectiva do PostgreSQL.
O DDL é transacional de acordo com este documento?
SQLite também parece ter DDL transacional. Consegui ROLLBACK
uma CREATE TABLE
declaração no SQLite. Sua CREATE TABLE
documentação não menciona nenhuma 'pegadinha' transacional especial.
ALTER TABLE
instrução um tanto limitada do SQLite também pode ser revertida. Não é mencionado explicitamente na documentação . O que é mencionado ali é como realizar mudanças "avançadas" dentro de uma transação.
O PostgreSQL tem DDL transacional para a maioria dos objetos de banco de dados (certamente tabelas, índices etc, mas não bancos de dados, usuários). No entanto, praticamente qualquer DDL obterá um ACCESS EXCLUSIVE
bloqueio no objeto de destino, tornando-o completamente inacessível até que a transação DDL seja concluída. Além disso, nem todas as situações são bem tratadas - por exemplo, se você tentar selecionar da tabela foo
enquanto outra transação a está descartando e criando uma tabela de substituição foo
, a transação bloqueada finalmente receberá um erro em vez de encontrar a nova foo
tabela. (Editar: isso foi corrigido em ou antes do PostgreSQL 9.3)
CREATE INDEX ... CONCURRENTLY
é excepcional, ele usa três transações para adicionar um índice a uma tabela enquanto permite atualizações simultâneas, portanto, ele não pode ser executado em uma transação.
Além disso, o comando de manutenção do banco de dados VACUUM
não pode ser usado em uma transação.
foo
enquanto outra transação está sendo descartada e recriada, então aceito a versão antiga ou erro. Não estou bem com a nova versão, porque ela ainda não foi confirmada, então não devo vê-la. Estou OK com um erro, porque no acesso transacional simultâneo, é preciso estar preparado para reiniciar as transações de qualquer maneira. Se ocorrerem erros com mais frequência do que o necessário, isso pode reduzir o desempenho, mas ainda está correto.
Embora não seja propriamente um "rollback", no Oracle o comando FLASHBACK pode ser usado para desfazer esses tipos de alterações, se o banco de dados foi configurado para suportá-lo.
Parece que as outras respostas estão bem desatualizadas.
Em 2019:
START TRANSACTION ... COMMIT;
. Portanto, você ainda não pode reverter instruções DDL em uma transação se a última na mesma transação falhar. (Consulte a nota sob dev. mysql.com/doc/refman/8.0/en/… )
Não pode ser feito com MySQL ao que parece, muito idiota, mas é verdade ... (de acordo com a resposta aceita)
"A instrução CREATE TABLE no InnoDB é processada como uma única transação. Isso significa que um ROLLBACK do usuário não desfaz as instruções CREATE TABLE que o usuário fez durante aquela transação."
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
Tentei de algumas maneiras diferentes e simplesmente não vai desistir ..
A alternativa é simplesmente definir um sinalizador de falha e "descartar a tabela tblname" se uma das consultas falhar.