• Nenhum resultado encontrado

Transa¸c˜ oes e Opera¸c˜ oes Atˆ omicas

No documento 1 Informa¸c˜ oes Gerais . . . . 1 (páginas 80-83)

1 Informa¸c˜ oes Gerais

1.8 Qual compatibilidade aos padr˜ oes o MySQL oferece ?

1.8.4 Diferen¸cas do MySQL em Compara¸c˜ ao com o SQL-92

1.8.4.3 Transa¸c˜ oes e Opera¸c˜ oes Atˆ omicas

O MySQL Server (vers˜ao 3.23-max e todas as vers˜oes 4.0 e acima) suportam transa¸c˜oes com osmecanismos de armazenamento transacionais InnoDB e BDB. InnoDBfornece compat-ibilidadetotal com ACID. Veja Cap´“ptexi tulo 7 [Tipos de tabelas], P´agina 629.

Os outros tipos de tabelas n˜ao transacionais (tais comoMyISAM) no MySQL Server seguem um paradigma diferente para integridade de dados chamado “Oper¸c~oes At^omicas.” Em termos de transa¸c˜ao, tabelasMyISAMefetivamente sempre operam em modoAUTOCOMMIT=1.

Opera¸c˜oes atˆomicas geralmente oferecem integridade compar´avel com a mais alta perfor-mance.

Com o MySQL Server suportando ambos os paradigmas, o usu´ario pode decidir se precisa da velocidade das opera¸c˜oes atˆomicas ou se precisa usar recursos transacionais em seu aplicativo. Esta escolha pode ser feita em uma base por tabela.

Como notado, a compara¸c˜ao para tabelas transacionais vs. n˜ao transacionais As noted, the trade off for transactional vs. non-transactional table se encontra em grande parte no desempenho. Tabelas transacionais tem uma exigˆencia de mem´oria e espa¸co em disco

significantemente maior e maior sobrecarga da CPU. Tipos de tabelas transacionais como InnoDB oferecem muitos recursos ´unicos. O projeto modular do MySQL Server permite o uso concorrente de todas estes mecanismos de armazenamento para servir a diferentes exigˆencias e oferecer um ´otimo desempenho em todas as situa¸c˜oes.

Mas como fazer uso dos recursos do MySQL Server para manter uma integridade rigorosa mesmo com tabelasMyISAMn˜ao transacionais e como este recurso se compara com os tipos de tabelas transacionais?

1. No paradigma transacional, se as suas aplica¸c˜oes s˜ao escritas de uma forma que ´e dependente na chamada de ROLLBACK em vez de COMMIT em situa¸c˜oes cr´iticas, ent˜ao transa¸c˜oes s˜ao mais convenientes. Al´em disso, transa¸c˜oes asseguram que atualiza¸c˜oes inacabadas ou atividades corrompidas n˜ao sejam executadas no banco de dados; o servidor oferece uma oportunidade para fazer um rollback autom´atico e seu banco de dados ´e mantido.

O MySQL Server, na maioria dos casos, permite a vocˆe resolver potenciais problemas incluindo simples conferˆencias antes das atualiza¸c˜oes e executando scripts simples que conferem inconsistˆencias no banco de dados e, automaticamente, repara ou avisa caso isto ocorra. Perceba que apenas usando o log do MySQL ou mesmo adicionando um log extra, pode-se corrigir tabelas perfeitamente sem nenhuma perda de integridade.

2. Mais do que nunco, atualiza¸c˜oes transacionais fatais podem ser reescritas para serem atˆomicas. De fato podemos dizer que todos problemas de integridade que transa¸c˜oes resolvem podem ser feitas comLOCK TABLESou atualiza¸c˜oes atˆomicas, assegurando que vocˆe nunca ir´a ter uma finaliza¸c˜ao autom´atica da tabela, o que ´e um problema comum em bancos de dados transacionais.

3. Nem mesmo transa¸c˜oes podem prevenir todas as falhas se o servidor cair. Nestes casos mesmo um sistema transacional pode perder dados. A diferen¸ca entre sistemas diferentes ´e apenas em qu˜ao pequeno ´e o lapso de tempo em que eles podem perder dados. Nenhum sistema ´e 100% seguro, somente “seguro o suficiente.” Mesmo o Oracle, com reputa¸c˜ao de ser o mais seguro bancos de dados transacionais, tem relatos de algumas vezes perder dados nestas situa¸c˜oes.

Para estar seguro com o MySQL Server, vocˆe apenas deve fazer backups e ter o log de atualiza¸c˜oes ligado. Com isto vocˆe pode se recuperar de qualquer situa¸c˜ao poss´ivel com bancos de dados transacionais. ´E sempre bom ter backups, independente de qual banco de dados vocˆe usa.

O paradigma transacional tem seus benef´icios e suas desvantagens. Muitos usu´arios e desenvolvedores de aplica¸c˜oes dependem da facilidade com a qual eles podem codificar contornando problemas onde abortar parece ser, ou ´e necess´ario. No entanto, se vocˆe

´e novo no paradigma de opera¸c˜oes atˆomicas ou tem mais familiaridade ou conforto com transa¸c˜oes, considere o benef´icio da velocidade que as tabelas n˜ao transacionais podem oferece, na ordem de 3 a 5 vezes da velocidade que as tabelas transacionais mais r´apidas e otimizadas.

Em situa¸c˜oes onde integridade ´e de grande importˆancia, as atuais caracter´isticas do MySQL permitem n´iveis transacionais ou melhor confian¸ca e integridade. Se vocˆe bloquear tabelas com LOCK TABLES todos as atualiza¸c˜oes ir˜ao ser adiadas at´e qualquer verifica¸c˜ao de inte-gridade ser feita. Se vocˆe s´o obter um bloqueio de leitura (oposto ao bloqueio de escrita),

ent˜ao leituras e inser¸c˜oes poder˜ao ocorrer. Os novos registros inseridos n˜ao poder˜ao ser vi-sualizados por nenhum dos clientes que tiverem um bloqueio deLEITURA at´e eles liberarem estes bloqueios. Com INSERT DELAYEDvocˆe pode enfileirar inser¸c˜oes em uma fila local, at´e os bloqueios serem liberados, sem que o cliente precise esperar at´a a inser¸c˜ao completar.

Veja Se¸c˜ao 6.4.3.2 [INSERT DELAYED], P´agina 581.

“Atˆomico”, no sentido em que n´os mencionamos, n˜ao ´e m´agico. Significa apenas que vocˆe pode estar certo que enquanto cada atualiza¸c˜ao espec´ifica est´a sendo executada, nenhum outro usu´ario pode interferir com ela, e nunca haver´a um rollback autom´atico (que pode acontecer em sistemas baseados em transa¸c˜oes se vocˆe n˜ao tiver muito cuidado). O MySQL tamb´em assegura que nunca ocorrer´a uma leitura suja.

A seguir est˜ao algumas t´ecnicas para trabalhar com tabelas n˜ao transacionais:

Loops que precisam de transa¸c˜oes normalmente pode ser codificados com a ajuda de LOCK TABLES, e vocˆe n˜ao precisa de cursores para atualizar regitros imeditamente.

Para evitar o uso do ROLLBACK, vocˆe pode usar as seguintes estrat´egias:

1. UseLOCK TABLES ...para fazer um lock todas as tabelas que vocˆe quer acessar.

2. Condi¸c˜oes de teste.

3. Atualize se estiver tudo OK.

4. UseUNLOCK TABLESpara liberar seus locks.

Isto ´e normalmente um m´etodo muito mais r´apido que usar transa¸c˜oes com poss´iveis ROLLBACKs, mas nem sempre. A ´unica situa¸c˜ao que esta solu¸c˜ao n˜ao pode tratar ´e quando algu´em mata a threads no meio de uma atualiza¸c˜ao. Neste caso, todas os locks ser˜ao liberados mas algumas das atualiza¸c˜ao podem n˜ao ter sido execuadas.

Vocˆe tamb´em pode usar fun¸c˜oes para atualizar registros em uma ´unica opera¸c˜ao. Vocˆe pode conseguir uma aplica¸c˜ao muito eficiente usando as seguintes t´ecnicas:

Modifique campos em rela¸c˜ao ao seus valores atuais.

Atualize apenas aqueles campos que realmente tiveram altera¸c˜oes.

Por exemplo, quando fazemos atualiza¸c˜oes em alguma informa¸c˜ao de cliente, atual-izamoa apenas os dados do clientes que alteraram e testamos apenas aqueles com dados alterados ou dados que dependem dos dados alterados, mudaram em compara¸c˜ao com o registro original. O teste dos dados alterados ´e feito com a cl´ausulaWHEREna instru¸c˜ao UPDATE. Se o registro n˜ao foi atualizado, mandamos ao cliente uma mensagem: ”Some of the data you have changed has been changed by another user.” Ent˜ao mostramos o registro antigo versus o novo em uma janela, assim o usu´ario pode decidir qual vers˜ao do registro de cliente de ser usado.

Isto nos d´a algo similar a lock de colunas mas que, na verdade, ´e melhor porque apenas atualizamos algumas das colunas, usando valores relativos ao seu valor atual. Isto significa que instru¸c˜oes UPDATEcomuns 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ˆe pode ver, isto ´e muito eficiente e funciona mesmo se outro cliente alterar os valores nas colunas pay_backou money_he_owes_us.

Em muitos casos, usu´arios querem fazer ROLLBACKe/ouLOCK TABLES com o prop´osito de gerenciarem identificadores ´unicos para algumas tabelas. Isto pode ser tratado muito mais eficientemente usando uma coluna AUTO_INCREMENT e tamb´em uma fun¸c˜ao SQL LAST_INSERT_ID() ou a fun¸c˜ao da API Cmysql_insert_id(). Veja Se¸c˜ao 12.1.3.31 [mysql_insert_id()], P´agina 799.

Geralmente vocˆe pode codificar evitando lock de registro. Algumas situa¸c˜oes realmente precisam disto, e tabelas InnoDB suportam lock de regitstro. Comoo MyISAM, vocˆe 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 MySQL retorna 1 para o n´umero de linhas afetadas se as linhas foram encontradas e row_flagj´a n˜ao era 1 na linha original.

Vocˆe pode pensar nisto como se o MySQL Server tivesse alterado a consulta anterior para:

UPDATE nome_tbl SET row_flag=1 WHERE id=ID AND row_flag <> 1;

No documento 1 Informa¸c˜ oes Gerais . . . . 1 (páginas 80-83)