Nesses últimos tempos, estou tentando entender muito mais como funciona, quando usar ou o porquê de certas tecnologias, principalmente que envolve System Design, e uma delas que estou estudando está sendo Banco de Dados, e nos meus estudos esses dias, me deparei com diversos termos, principalmente sendo somente iniciais de palavras, com isso decidi ir mais a fundo sobre eles compilando o que aprendi.
Table of contents
O que é
ACID simplesmente é um acrônimo (conjunto de letras) para as palavras em inglês Atomicity, Consistency, Isolation e Durability, que em português significam Atomicidade, Consistência, Isolamento e Durabilidade. Para contexto histórico, foi inventado em 1983 por Andreas Reuter e Theo Härder. A ideia por trás do ACID é de serem propriedades que vão servir de paradigmas para as transações realizadas nos bancos de dados, paradigmas esses que prezam bastante a consistência de informações. Esse paradigma é adotado por todos os bancos relacionais (SQL) como Postgres e MySQL, só que hoje em dia, já é adotado por bancos não relacionais como MongoDB ou FoundationDB, tem vários outros só que ainda parcialmente. A importância desse paradigma surgiu quando começamos a ter contextos que precisavam de grande consistência de dados, como um exemplo mais famoso, o contexto financeiro, onde um erro pode ser muito grave. Agora vamos para a explicação de cada letra.
A
Essa letra é para a palavra em inglês Atomicity ou Atomicidade em português, que usamos para expressar que algo é atômico, ou seja, algo que não é feito em partes, é feito completo. Essa parte do paradigma foi criada com o intuito de que as transações realizadas para os bancos de dados sejam executadas completamente, sem nenhum tipo de parcialidade, sendo a famosa frase que todo mundo fala quando vai explicar "é tudo executado ou nada é executado", não vai existir um meio termo ou parte executada porque ela existe para manter a consistência dos dados, no final, todo o paradigma é com o intuito de manter a consistência dos dados.
C
Agora vamos para Consistency ou Consistência, que tem como objetivo manter a consistência das regras, ou da integridade dos casos. Por exemplo, temos uma loja, para que o cliente faça uma compra, precisamos que ele seja um usuário para vincular a compra ao usuário dele. Dependendo da forma que você for modelar, vai precisar usar Chave Estrangeira (FK), isso por si só já é uma forma de regras para os dados e ao mesmo tempo de manter a integridade dos dados.
I
Esse é o Isolation ou Isolação, que tem como ideia que uma transação não pode interromper outra transação. Trazendo para um exemplo prático, se eu quiser ver as informações de um usuário na plataforma ao mesmo tempo que outra pessoa está querendo ver as informações ou editar simultaneamente, nenhuma das nossas transações vai atrapalhar a outra.
D
Por último, Durability ou Durabilidade, é o mais simples de entender que é, todas as transações têm que ser persistidas, independente de qualquer tipo de falha como queda de internet, luz e etc
Na prática
Vamos subir um ambiente PostgreSQL, usando como ambiente de exemplo o financeiro e de maneira muito simples, então vamos focar somente em como acontece na prática.
Crie uma tabela
CREATE TABLE contas ( id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, nome TEXT, saldo NUMERIC );
Insira as seguintes informações
INSERT INTO contas (nome, saldo) VALUES ('Fulano', 100), ('Ciclano', 50);
Vamos fazer uma transferência (adição de saldo)
BEGIN;
UPDATE contas
SET saldo = saldo - 50
WHERE id = 1;
UPDATE contas
SET saldo = saldo + 30
WHERE id = 2;
COMMIT;
Obs: Foi feita aqui uma transação, se olharem bem, teve o BEGIN da transação e, por último o COMMIT, com isso finalizando a transação.
Após o COMMIT, Fulano vai ter saldo de 50 e Ciclano vai ter de 80, mas se algum momento ocorresse um erro por usar algum campo errado no update ou set, a transação iria usar o ROLLBACK para desfazer tudo que deu certo, com isso, mantivemos a atomicidade dos dados.
Seguindo com o mesmo exemplo, vamos criar uma regra de negócio que é: Saldo nunca pode ficar abaixo de zero.
Vamos usar a constraint para isso:
ALTER TABLE contas ADD CONSTRAINT saldo_positivo CHECK (saldo >= 0);
Vamos tentar adicionar um valor abaixo de zero:
BEGIN;
UPDATE contas
SET saldo = saldo - 60
WHERE id = 1;
COMMIT;
O PostgreSQL vai responder:
BEGIN
ERROR: new row for relation "contas" violates check constraint "saldo_positivo"
DETAIL: Failing row contains (1, Fulano, -10).
ROLLBACK
Por conta de que ele precisa manter a consistência de dados, com isso, respeitar a regra criada. Abrindo dois terminais, digite em um o comando sem COMMIT:
BEGIN;
UPDATE contas
SET saldo = saldo + 500
WHERE id = 1;
No outro terminal, digite o comando:
SELECT * FROM contas WHERE id=1;
Vai retornar:
id | nome | saldo
----+--------+-------
1 | Fulano | 50
(1 row)
Isso acontece por conta de que no primeiro terminal a transação não foi commitada, então a informação ainda não foi realmente atualizada, com isso, no primeiro terminal rode o comando:
COMMIT;
Rodando novamente no segundo terminal o comando:
SELECT * FROM contas WHERE id=1;
Vai ser retornado:
id | nome | saldo
----+--------+-------
1 | Fulano | 550
(1 row)
Com isso, vemos que foi mantido o isolamento entre as transações, com nenhuma transbordando para a outra.
O último é bem difícil, quase impossível de demonstrar, mas imagina que você fez uma transação de adição de saldo para a conta 1, só que antes de o banco realizar o Commit, caiu a luz de onde está o seu banco de dados. O PostregSQL tem uma tecnologia de log chamada WAL (Write Ahead Log) que vai salvar em disco o log dessa transação e, após o banco retornar, vai refazer a alteração.
Conclusão
Eu achei bem interessante aprender sobre ACID e também BASE (futuramente vou trazer sobre), porque mostra um dos vários motivos de como se escolher quando deve ser usado um banco relacional e um não relacional, e isso era uma coisa que sempre tive dúvida em projetos, e com conhecimento sobre esses paradigmas, se entende que dependendo do contexto que for, é bem importante usar um tipo de banco do que o outro.
Top comments (0)