Este texto é o primeiro de uma série sobre transações de dados e como se comportam em aplicações simples e em uma arquitetura de sistemas distribuídos. Quais propriedades essas transações possuem e como se pode tomar proveito de cada uma dessas propriedades.
Num SGBD (sistema gerenciador de banco de dados), uma transação é a unidade lógica de trabalho executada sobre um banco de dados. Tratada de maneira coerente e confiável, independente de outras transações, sendo às vezes composta de várias operações. Qualquer cálculo lógico feito em um banco de dados é denominado de transação.
Um exemplo, provavelmente o mais clássico de universo, é a transferência de uma conta bancária para outra: a transação completa requer a subtração do valor a ser transferido de uma conta e a adição da mesma quantia à outra. Neste exemplo, não é uma boa ideia que apenas uma operação, a adição ou a subtração, seja realizada com sucesso (embora seria divertido se ao transferir, nenhum dinheiro fosse debitado da minha conta). Só existindo duas possibilidades admissíveis: 1) as duas operações são bem-sucedidas, 2) nenhuma é.
À esta propriedade, dá-se o nome de atomicidade. Discorro um sobre essa propriedade e algumas outras logo mais abaixo.
Transações ACID
Em um banco de dados relacional há a exigência, por definição, que as transações sejam atômicas, consistentes, isoladas e duráveis. É comum se referir a essas propriedades de transações de bancos de dados usando o termo ACID. O acrônimo, embora superficialmente definido, é bastante popular na indústria desde quase sempre.
- Atomicidade: Todas as ações que compõem a unidade de trabalho da transação devem ser concluídas com sucesso para que seja efetivada. Se durante a transação qualquer ação que constitui unidade de trabalho falhar, a transação inteira deve ser desfeita (rollback). Quando todas as ações são efetuadas com sucesso, a transação pode ser efetivada e persistida (commit).
- Consistência: Todas as regras e restrições definidas no banco de dados devem ser obedecidas. Relacionamentos por chaves estrangeiras, checagem de valores para campos restritos ou únicos devem ser obedecidos para que uma transação possa ser completada com sucesso.
- Isolamento: Cada transação funciona completamente à parte de outras estações. Nenhuma outra transação, operando no mesmo sistema, pode interferir no funcionamento da transação corrente. Transações não podem visualizar os resultados parciais de outras..
- Durabilidade: Os resultados de uma transação são permanentes e podem ser desfeitos somente por uma transação subsequente. Erros por falha de hardware não são aceitáveis.
Essas propriedades reinaram soberanas no mundo durante décadas, porém, a natureza restritiva limita sua aplicação e, por vezes, não são compatíveis com os softwares modernos. Ora, dependendo da situação, é perfeitamente aceitável que se abra mão de uma delas visando responsividade e elasticidade de um sistema reativo. Veja, a durabilidade de um cache pode não ser tão importante quanto uma busca mais eficiente, ou o custo do acesso ao disco rígido pode ser mais caro do que o custo da inconsistência. Ao se permitir afrouxar a rigidez dessas características, um espectro inteiro de transações de dados se abre. Onde em um extremo encontramos as transações ACID e, no outro extremo, as transações não ACID, frequentemente chamadas de transações BASE.
Química avançada
Antes de falar sobre a definição dessas transações, permitam-me falar um pouco sobre química.
Neutralização
A neutralização é uma reação química entre um ácido e uma base de modo que o pH do meio é neutralizado e se produz água e um sal.
O exemplo clássico de uma neutralização (e o único que sei de cabeça) é a reação entre ácido clorídrico (HCl) e hidróxido de sódio/soda cáustica (NaOH) que gera sal de cozinha (NaCl) e água (H₂O):
HCl + NaOH → NaCl + H₂O
Fissão atômica
Aproveitando a ocasião, saliento que a palavra “átomo” também é oriundo da química. Lá pelas tantas de algum século recente, os cientistas usaram pela primeira vez para descrever o que acreditavam ser o menor pedaço de um elemento. Eles assim o denominaram porque o significado, do grego, é: “indivisível”. Formado a partir de ἀ- (a-, “não”) e τέμνω (temnō, “cortar”). Posteriormente, foi descoberto que os átomos podem ser divididos, mas já era muito tarde para mudar um termo que bombava na academia.
No atômico do ACID, assim como no sentido original da química**,** as ações que compõem a transação são indivisíveis. Tudo ou nada, oito ou oitenta, sem meio termo. Independentemente do que os químicos argumentarem. Eles que venham programar, caso persistam na teimosia.
Justificativa
Por que criei essa seção? Primeiro para me exibir e dizer que lembro de algumas aulas de química. Segundo porque pretendo valorizar a criatividade e o empenho da galera de desenvolvimento de software: foram lá na química achar umas propriedades e fizeram contorcionismo para fazer disso conceitos computacionais (embora sua precisão e utilidade seja discutível). Palmas. Acredito que esses motivos somados justificam, mesmo que ligeiramente, essa pequena seção neste texto
Transações BASE
O acrônimo BASE foi definido por Eric Brewer (a quem destinei aquelas palmas acima) e é usado para descrever as propriedades de alguns banco de dados, geralmente bancos NoSQL). A sigla talvez seja ainda mais superficial do que ACID pois tem um significado vago e abrangente. Mas não posso deixar de explicá-lo. Basicamente disponível, estado soft e consistência eventual (do original, em inglês, Basically Available, Soft state, Eventual consistency)
- Basicamente disponível: Foco na disponibilidade de dados mesmo diante de múltiplas falhas por meio de uma abordagem de gerenciamento distribuído.
- Estado soft: Sem uma atualização, os dados expirarão ou serão excluídos. O estado pode mudar com o tempo, mesmo sem solicitação. Ou seja, a consistência é um problema do desenvolvedor e não deve ser tratada pelo SGBD.
- Consistência eventual: Em algum ponto do futuro, sem garantias, no entanto, quanto ao momento, os dados convergirão para um estado consistente. A medida que as alterações são propagadas para as réplicas. De forma que as consultas de dados podem não retornar dados atualizados imediatamente ou podem resultar na leitura de dados não precisa, um problema conhecido como leitura obsoleta.
As propriedades BASE são bem mais frouxas do que as ACID e não há um mapeamento direto entre elas (um argumento que provavelmente será contestado).
Navegando pelo balanceamento ACID-BASE
Não existe uma resposta direta sobre se sua aplicação precisa de um modelo ACID ou BASE. Na verdade, essa propriedade se trata de um espectro e não de uma escolha binária. Na química, o limão (pH 1,8) e a laranja (pH 3,9), apesar de ácidos, possuem graus distintos de acidez. Valores intermediários de grau de acidez também se aplicam nas transações de dados. Uma transação não precisa ser 100% ácida ou 100% básica, não é 8 ou 80. Valores intermediários são perfeitamente aceitáveis.
Perceba, em um e-commerce, porque exemplos e e-commerce são sinônimos, a diferença entre ter 104 ou 103 livros no estoque é, em muitas vezes, irrisória, logo, podemos neutralizar a consistência dessa operação.
Daqui poucos segundos, pode ser atualizado para 102. Ou mais, é possível que seja mais barato repor uma peça do estoque por conta de uma venda indevida do que impedir a compra e prejudicar a experiência do usuário.
Não é um cálculo trivial e muitas regras de negócio devem ser levadas em consideração. Desenvolvedores e arquitetos de dados deverão ponderar o ponto ideal caso a caso para a circunstância baseado no que é mais importante para a situação e não apenas baseado no que está bombando no twitter ou no modelo previamente adotado. Cogitando, inclusive, múltiplas adoções para resolver o problema.
Por mais que abrir mão de um dos pontos das transações ACID possa parecer inicialmente doloroso e arriscado, reforça-se que a maioria dos bancos NoSQL o faz. Redis, por exemplo, desconsidera a durabilidade; Cassandra, a consistência e o Riak, a atomicidade. No entanto, alguns outros como MarkLogic, Aerospike e OrientDB as tornaram centrais em seus projetos.
pH em transações distribuídas
Em um sistema monolítico, o SGBD garante o pH ácido ou básico das transações, mas como medi-lo no contemporâneo mundo dos sistemas distribuídos onde, por padrão, não há um coordenador de transações?
Um dos sistemas possuir uma base de dados com operações atômicas não implica que as transações pelo ecossistema também são e o mesmo se aplica para a consistência, isolamento e durabilidade.
É possível, inclusive, que uma arquitetura distribuída seja inteiramente constituída de SGBDs ÁCIDos e ainda assim suas transações não sejam consistentes.
Para saber essas respostas e se entreter um pouco mais, leia a continuação deste post: