Transações e Operações Atômicas
O MariaDB Server (versão 3.23-max e todas as versões 4.0 e acima) suportam transações com os mecanismos de armazenamento transacionais
InnoDB
e BDB
. InnoDB
fornece compatibilidade total com ACID
. Leia Tipos de Tabela do MariaDB.
Os outros tipos de tabelas não transacionais (tais como MyISAM
) no MariaDB Server seguem um paradigma diferente para integridade de dados chamado
Em termos de transação, tabelas Operções Atômicas
.MyISAM
efetivamente sempre operam em modo AUTOCOMMIT=1
. Operações atômicas geralmente oferecem integridade comparável com a mais alta performance.
Com o MariaDB Server suportando ambos os paradigmas, o usuário pode decidir se precisa da velocidade das operações atômicas ou se precisa usar recursos transacionais em seu aplicativo. Esta escolha pode ser feita em uma base por tabela.
Como notado, a comparação para tabelas transacionais vs. não transacionais As noted, the trade off for transactional vs. non-transactional table se encontra em grande parte no desempenho. Tabelas transacionais tem uma exigência de memória e espaço em disco significantemente maior e maior sobrecarga da CPU. Tipos de tabelas transacionais como InnoDB
oferecem muitos recursos únicos. O projeto modular do MariaDB Server permite o uso concorrente de todas estes mecanismos de armazenamento para servir a diferentes exigências e oferecer um ótimo desempenho em todas as situações.
Mas como fazer uso dos recursos do MariaDB Server para manter uma integridade rigorosa mesmo com tabelas MyISAM
não transacionais e como este recurso se compara com os tipos de tabelas transacionais?
- No paradigma transacional, se as suas aplicações são escritas de uma forma que é dependente na chamada de
ROLLBACK
em vez deCOMMIT
em situações críticas, então transações são mais convenientes. Além disso, transações asseguram que atualizações inacabadas ou atividades corrompidas não sejam executadas no banco de dados; o servidor oferece uma oportunidade para fazer um rollback automático e seu banco de dados é mantido.O MariaDB Server, na maioria dos casos, permite a você resolver potenciais problemas incluindo simples conferências antes das atualizações e executando scripts simples que conferem inconsistências no banco de dados e, automaticamente, repara ou avisa caso isto ocorra. Perceba que apenas usando o log do MariaDB ou mesmo adicionando um log extra, pode-se corrigir tabelas perfeitamente sem nenhuma perda de integridade.
- Mais do que nunco, atualizações transacionais fatais podem ser reescritas para serem atômicas. De fato podemos dizer que todos problemas de integridade que transações resolvem podem ser feitas com
LOCK TABLES
ou atualizações atômicas, assegurando que você nunca irá ter uma finalização automática da tabela, o que é um problema comum em bancos de dados transacionais. - Nem mesmo transações podem prevenir todas as falhas se o servidor cair. Nestes casos mesmo um sistema transacional pode perder dados. A diferença entre sistemas diferentes é apenas em quão pequeno é o lapso de tempo em que eles podem perder dados. Nenhum sistema é 100% seguro, somente
seguro o suficiente.
Mesmo o Oracle, com reputação de ser o mais seguro bancos de dados transacionais, tem relatos de algumas vezes perder dados nestas situações.Para estar seguro com o MariaDB Server, você apenas deve fazer backups e ter o log de atualizações ligado. Com isto você pode se recuperar de qualquer situação possível com bancos de dados transacionais. É sempre bom ter backups, independente de qual banco de dados você usa.
O paradigma transacional tem seus benefícios e suas desvantagens. Muitos usuários e desenvolvedores de aplicações dependem da facilidade com a qual eles podem codificar contornando problemas onde abortar parece ser, ou é necessário. No entanto, se você é novo no paradigma de operações atômicas ou tem mais familiaridade ou conforto com transações, considere o benefício da velocidade que as tabelas não transacionais podem oferece, na ordem de 3 a 5 vezes da velocidade que as tabelas transacionais mais rápidas e otimizadas.
Em situações onde integridade é de grande importância, as atuais características do MariaDB permitem níveis transacionais ou melhor confiança e integridade. Se você bloquear tabelas com LOCK TABLES
todos as atualizações irão ser adiadas até qualquer verificação de integridade ser feita. Se você só obter um bloqueio de leitura (oposto ao bloqueio de escrita), então leituras e inserções poderão ocorrer. Os novos registros inseridos não poderão ser visualizados por nenhum dos clientes que tiverem um bloqueio de LEITURA
até eles liberarem estes bloqueios. Com INSERT DELAYED
você pode enfileirar inserções em uma fila local, até os bloqueios serem liberados, sem que o cliente precise esperar atá a inserção completar. Leia "Sintaxe INSERT DELAYED
".
Atômico
, no sentido em que nós mencionamos, não é mágico. Significa apenas que você pode estar certo que enquanto cada atualização específica está sendo executada, nenhum outro usuário pode interferir com ela, e nunca haverá um rollback automático (que pode acontecer em sistemas baseados em transações se você não tiver muito cuidado). O MariaDB também assegura que nunca ocorrerá uma leitura suja.
A seguir estão algumas técnicas para trabalhar com tabelas não transacionais:
- Loops que precisam de transações normalmente pode ser codificados com a ajuda de
LOCK TABLES
, e você não precisa de cursores para atualizar regitros imeditamente. - Para evitar o uso do
ROLLBACK
, você pode usar as seguintes estratégias:- Use
LOCK TABLES ...
para fazer um lock todas as tabelas que você quer acessar. - Condições de teste.
- Atualize se estiver tudo OK.
- Use
UNLOCK TABLES
para liberar seus locks.
Isto é normalmente um método muito mais rápido que usar transações com possíveis
ROLLBACK
s, mas nem sempre. A única situação que esta solução não pode tratar é quando alguém mata a threads no meio de uma atualização. Neste caso, todas os locks serão liberados mas algumas das atualização podem não ter sido execuadas. - Use
- Você também pode usar funções para atualizar registros em uma única operação. Você pode conseguir uma aplicação muito eficiente usando as seguintes técnicas:
- Modifique campos em relação ao seus valores atuais.
- Atualize apenas aqueles campos que realmente tiveram alterações.
Por exemplo, quando fazemos atualizações em alguma informação de cliente, atualizamoa apenas os dados do clientes que alteraram e testamos apenas aqueles com dados alterados ou dados que dependem dos dados alterados, mudaram em comparação com o registro original. O teste dos dados alterados é feito com a cláusula
WHERE
na instruçãoUPDATE
. Se o registro não foi atualizado, mandamos ao cliente uma mensagem: ''Some of the data you have changed has been changed by another user.'' Então mostramos o registro antigo versus o novo em uma janela, assim o usuário pode decidir qual versão do registro de cliente de ser usado.Isto nos dá algo similar a lock de colunas mas que, na verdade, é melhor porque apenas atualizamos algumas das colunas, usando valores relativos ao seu valor atual. Isto significa que instruções
UPDATE
comuns se parecem com estas:UPDATE nometabela SET pay_back=pay_back+125; UPDATE customer SET customer_date='current_date', address='new address', phone='new phone', money_he_owes_us=money_he_owes_us-125 WHERE customer_id=id AND address='old address' AND phone='old phone';
Como você pode ver, isto é muito eficiente e funciona mesmo se outro cliente alterar os valores nas colunas
pay_back
oumoney_he_owes_us
. - Em muitos casos, usuários querem fazer
ROLLBACK
e/ouLOCK TABLES
com o propósito de gerenciarem identificadores únicos para algumas tabelas. Isto pode ser tratado muito mais eficientemente usando uma colunaAUTO_INCREMENT
e também uma função SQLLAST_INSERT_ID()
ou a função da API Cmysql_insert_id()
. Leia "mysql_insert_id()
".Geralmente você pode codificar evitando lock de registro. Algumas situações realmente precisam disto, e tabelas
InnoDB
suportam lock de regitstro. Comoo MyISAM, você pode usar uma coluna de flag na tabela e fazer algo como a seguir:UPDATE nome_tbl SET row_flag=1 WHERE id=ID;
O MariaDB retorna 1 para o número de linhas afetadas se as linhas foram encontradas e
row_flag
já não era 1 na linha original.Você pode pensar nisto como se o MariaDB Server tivesse alterado a consulta anterior para: