FolioPierEstudos de TI

Gravar direto no banco

Nota 26 de 41 · 6 min de leitura
Nesta página
  1. O que o SQL direto deixa de fora
  2. A origem do dado
  3. Preparar a alteração
  4. Executar e conferir
  5. Depois da confirmação
  6. Quando a conexão cai ou surge um erro

Uma correção feita por SQL pode resolver um campo e deixar a busca, os relacionamentos ou os totais do sistema incoerentes. O banco executa o comando recebido e não passa pelas conferências nem pelos cálculos da aplicação. Por isso, uma alteração direta no banco segue um procedimento próprio, com preparação, conferência e validação.

O que o SQL direto deixa de fora

  • Conferências da aplicação: as regras de negócio e as ligações entre tabelas mantidas apenas no código.
  • Marca de exclusão: o DELETE remove a linha, sem a marca que a aplicação usaria.
  • Colunas derivadas: um UPDATE na coluna de origem não recalcula a coluna derivada.
  • Registro das alterações: muitas aplicações anotam cada alteração para a sincronização com a matriz ou para a auditoria, e uma alteração direta não entra nesse registro.
  • Identidade: um INSERT sem a coluna da chave primária recebe um identificador novo.

O SQL direto continua sujeito às permissões da conta e às regras declaradas no banco, como os tipos das colunas, os valores únicos e o modo estrito. O que ele contorna são as regras que existem só na aplicação.

A origem do dado

Antes de corrigir um dado na loja, convém saber de onde ele vem. Um preço enviado pela matriz e corrigido direto no banco da loja volta ao valor da matriz na próxima sincronização, ou passa a divergir dela. A correção de um dado que vem de outra origem é feita na própria origem.

Preparar a alteração

  1. SELECT @@hostname, DATABASE();: confirma o servidor e o banco da conexão;
  2. SELECT id, nome FROM clientes WHERE id = 10;: mostra as linhas que a condição atinge;
  3. CREATE TABLE clientes_antes_20261008 AS SELECT * FROM clientes WHERE id = 10;: guarda uma cópia dessas linhas no próprio banco.

A cópia guarda o estado anterior das linhas e não precisa de índices. Por ser uma mudança de estrutura, esse comando confirma qualquer transação aberta e por isso vem antes da transação da correção. Uma alteração em muitas linhas pede, além dessa cópia, uma cópia de segurança da tabela inteira.

A preparação também identifica o que depende das linhas: as colunas derivadas, as tabelas que apontam para elas e o registro de alterações da aplicação.

Executar e conferir

  1. START TRANSACTION;: abre a transação;
  2. UPDATE clientes SET nome = 'José da Silva' WHERE id = 10;: faz a correção, com a mesma condição do SELECT da preparação;
  3. SELECT id, nome FROM clientes WHERE id = 10;: confere o resultado na mesma conexão.

O número de linhas encontradas pelo UPDATE precisa bater com o SELECT da preparação. Um UPDATE que encontra a linha já com o valor pedido informa zero linhas alteradas, e isso não significa que a linha não existe. O comando SHOW WARNINGS; mostra os avisos do último comando, como um valor cortado em um servidor fora do modo estrito. Com o resultado conferido, o COMMIT confirma a correção, e, diante de qualquer diferença, o ROLLBACK a desfaz.

Essa proteção vale só para as tabelas InnoDB. Em uma tabela MyISAM, a correção vale no fim do próprio UPDATE, o ROLLBACK termina com o aviso 1196, sem desfazer nada, e a volta ao estado anterior depende da cópia guardada na preparação.

Se outras estações gravam na mesma tabela, a preparação e a alteração podem encontrar estados diferentes. Uma correção que atinge muitas linhas pede um horário de pouco movimento ou uma janela de manutenção combinada.

Depois da confirmação

A correção só termina depois de algumas etapas:

  • a validação na própria aplicação, na tela, na busca e nos relatórios que usam os dados;
  • o recálculo das colunas derivadas pela rotina da aplicação, quando a correção atingiu uma coluna de origem;
  • o registro do que foi feito, com a data, a hora, o servidor, o banco, o comando, as linhas atingidas e o motivo;
  • a remoção da tabela de cópia, depois da validação, conforme o procedimento da equipe.

Quando a conexão cai ou surge um erro

Em uma tabela InnoDB, quando a conexão cai antes do COMMIT, o MySQL desfaz a alteração pendente, e, quando cai depois, a alteração vale. Em uma tabela MyISAM, nada fica pendente. O que o comando gravou vale, e um comando interrompido no meio, por um KILL ou por uma parada abrupta do serviço, pode deixar só parte das linhas alteradas. Como nem sempre é possível saber em qual momento a queda aconteceu, a repetição de uma correção começa pela consulta aos dados. A repetição cega de uma alteração acumulativa aplica o valor duas vezes:

  • UPDATE produtos SET estoque = estoque + 5 WHERE id = 315;: soma cinco unidades ao estoque a cada execução.

Um erro no meio da transação também exige atenção. O tempo de espera esgotado desfaz só a instrução que esperou, o deadlock desfaz a transação inteira, e o estado da conexão precisa ser conferido antes de qualquer COMMIT.

No suporte

Antes de confirmar uma correção feita por SQL, convém conferir a condição, guardar o estado anterior das linhas e validar o resultado na mesma conexão. Quando a correção atinge uma coluna de origem, a forma de manter as colunas derivadas precisa estar definida antes. O COMMIT só encerra uma correção cujo efeito foi compreendido.

Para guardar

  • O SQL direto contorna as regras e os cálculos que existem só na aplicação.
  • Um dado que vem da matriz é corrigido na origem.
  • A preparação confirma o servidor e o banco, mostra as linhas atingidas e guarda o estado anterior.
  • Nas tabelas InnoDB, a transação permite conferir o resultado antes do COMMIT, e, nas MyISAM, só a cópia permite voltar atrás.
  • Depois de uma queda, a repetição começa pela consulta aos dados.
Depois de um UPDATE errado, o ROLLBACK não desfez nada. O que conferir?

Se a confirmação automática estava ligada, sem START TRANSACTION, se houve um COMMIT ou um comando de estrutura no meio, se o ROLLBACK foi enviado pela mesma conexão e se a tabela é MyISAM. Em qualquer desses casos, a alteração já valia. A recuperação usa a cópia do estado anterior guardada na preparação.

A conexão caiu logo depois de um UPDATE que somava cinco unidades ao estoque de um produto. É seguro repetir o comando?

Não sem conferir os dados. Em uma tabela InnoDB, se a queda aconteceu antes da confirmação, a alteração foi desfeita, e, se aconteceu depois, a alteração vale. Em uma tabela MyISAM, a alteração vale desde o fim do comando. Repetir sem conferir pode somar as cinco unidades duas vezes. A comparação do estoque atual com o valor guardado na preparação mostra o que aconteceu.

Publicado a partir do Obsidian · FolioPier