Leitores como você ajudam a apoiar o MUO. Quando você faz uma compra usando links em nosso site, podemos ganhar uma comissão de afiliado.

Construir um aplicativo da Web pronto para produção exige que você garanta que ele seja seguro e escalável.

Uma das coisas mais importantes a saber sobre bancos de dados é o princípio ACID, que significa atomicidade, consistência, isolamento e durabilidade. Bancos de dados relacionais como MySQL suportam transações ACID nativamente. Mas o MongoDB é um banco de dados NoSQL e não suporta transações ACID por padrão.

Como programador, você deve saber como introduzir propriedades ACID em seus bancos de dados MongoDB.

O que são transações de banco de dados?

Uma transação de banco de dados é uma sequência de consultas ou operações de banco de dados que são executadas juntas como uma unidade para concluir uma tarefa.

As transações do banco de dados aderem aos conceitos das características do ACID. Isso ajuda a garantir que nenhuma alteração ocorra, a menos que todas as operações sejam bem-sucedidas. Ele também garante que o banco de dados seja consistente.

As propriedades ACID explicadas

As quatro propriedades que compõem os princípios ACID são:

  • Atomicidade é a propriedade que conceitua transações como pequenas unidades de um programa. Isso implica que todas as consultas são executadas com êxito ou falham juntas.
  • Consistência afirma que os registros do banco de dados devem permanecer consistentes antes e depois de cada transação.
  • Isolamento garante que, quando várias transações são executadas simultaneamente, uma não afeta a outra.
  • Durabilidade concentra-se em falhas ou falhas do sistema. Ele garante que uma transação confirmada não seja perdida em caso de falha do sistema. Isso pode envolver técnicas necessárias para restaurar os dados de um backup automaticamente assim que o sistema for ativado novamente.

Como implementar transações de banco de dados MongoDB em Node.js usando Mongoose

MongoDB tornou-se uma tecnologia de banco de dados amplamente utilizada ao longo dos anos devido a sua natureza NoSQL e modelo baseado em documento flexível. Ele também oferece a capacidade de organizar melhor seus dados e com mais flexibilidade do que em bancos de dados SQL ou relacionais.

Para implementar transações de banco de dados no MongoDB, você pode considerar um cenário de amostra em um aplicativo de listagem de empregos em que um usuário pode postar, atualizar ou excluir um trabalho. Aqui está um projeto de esquema de banco de dados simples para este aplicativo:

Para acompanhar, esta seção requer conhecimento básico de programação Node.js e MongoDB.

As transações não têm suporte em instalações autônomas do MongoDB. Você precisará usar um Conjunto de réplicas do MongoDB ou Cluster fragmentado do MongoDB para que as transações funcionem. Portanto, a maneira mais fácil de usar transações é criar uma instância do MongoDB hospedada na nuvem (MongoDB Atlas). Por padrão, cada instância do banco de dados Atlas é um conjunto de réplicas ou um cluster fragmentado.

Depois de configurar um projeto Node.js e MongoDB funcional, você pode configurar uma conexão com um banco de dados Mongo no Node.js. Se ainda não o fez, instale o mangusto executando npm instalar mangusto em seu terminal.

importar mangusto de 'mangusto'

deixe MONGO_URL = process.env. MONGO_URL || 'seu-banco-de-banco-url-mongo';

deixar conexão;
const conectarDb = assíncrono () => {
tentar {
aguardam mongoose.connect (MONGO_URL, {
useNewUrlParser: verdadeiro,
useUnifiedTopology: verdadeiro,
});

console.log("CONECTADO AO BANCO DE DADOS");
conexão = mangusto.conexão;
} pegar (err) {
console.error("FALHA NA CONEXÃO DO BANCO DE DADOS!");
console.erro(errar.mensagem);
processo.saída(1); // fecha o aplicativo se a conexão com o banco de dados falhar
}
};

Você deve armazenar a conexão em uma variável para poder usá-la para iniciar uma transação posteriormente no programa.

Você pode implementar as coleções de usuários e tarefas da seguinte forma:

const userSchema = novo mangusto. Esquema({
nome: Corda,
e-mail: Corda,
empregos: [mangusto. Esquema. Tipos. ObjectId]
});

const jobSchema = novo mangusto. Esquema({
título: Corda,
localização: Corda,
salário: Corda,
poster: mangusto.Esquema.Tipos.ObjectId
});

const userCollection = mongoose.model('do utilizador', userSchema);
const jobCollection = mongoose.model('trabalho', jobSchema);

Você pode escrever uma função para adicionar um usuário ao banco de dados assim:


const criarUsuário = assíncrono (usuário) => {
const novoUsuário = aguardam userCollection.create (usuário);
console.log("Usuário adicionado ao banco de dados");
console.log (novoUsuário);
}

O código abaixo demonstra a função para criar um trabalho e adicioná-lo à lista de trabalhos de seu anunciante usando uma transação de banco de dados.


const criarJob = assíncrono (trabalho) => {
const { userEmail, cargo, localização, salário } = trabalho;

// obtém o usuário do banco de dados
const usuário = aguardam userCollection.findOne({ e-mail: usuárioEmail });

// inicia sessão de transação
const sessão = aguardam connection.startSession();

// executa todas as consultas ao banco de dados em um bloco try-catch
tentar {
aguardam sessão.startTransaction();

// cria trabalho
const newJob = aguardam jobCollection.create(
[
{
título,
localização,
salário,
cartaz: user._id,
},
],
{ sessão }
);
console.log("Criado novo trabalho com sucesso!");
console.log (novoJob[0]);

// adiciona trabalho à lista de usuários de trabalhos postados
const newJobId = newJob[0]._eu ia;
const adicionadoToUser = aguardam userCollection.findByIdAndUpdate(
ID do usuário,
{ $addToSet: { empregos: newJobId } },
{ sessão }
);

console.log("Trabalho adicionado com sucesso à lista de trabalhos do usuário");
console.log (addedToUser);

aguardam sessão.commitTransaction();

console.log("Transação DB realizada com sucesso");
} pegar (e) {
console.erro (e);
console.log("Falha ao concluir as operações do banco de dados");
aguardam session.abortTransaction();
} finalmente {
aguardam sessão.endSession();
console.log("Sessão de transação encerrada");
}
};

A criar A consulta executada em uma transação geralmente recebe e retorna uma matriz. Você pode ver isso no código acima, onde ele cria novo emprego e armazena seu _eu ia propriedade nonewJobId variável.

Aqui está uma demonstração de como as funções acima funcionam:

const mockUser = {
nome: "Timmy Omolana",
e-mail: "[email protected]",
};

const mockJob = {
título: "Gerente de Vendas",
localização: "Lagos, Nigéria",
salário: "$40,000",
userEmail: "[email protected]", // email do usuário criado
};

const startServer = assíncrono () => {
aguardam conectarDb();
aguardam criarUsuário (mockUsuário);
aguardam criarJob (mockJob);
};

startServer()
.então()
.catch((erro) => console.log (erro));

Se você salvar este código e executá-lo usando npm start ou o comando, ele deve produzir uma saída como esta:

Outra maneira de implementar transações ACID no MongoDB usando o Mongoose é usando o método withTransaction() função. Essa abordagem fornece pouca flexibilidade, pois executa todas as consultas dentro de uma função de retorno de chamada que você passa como um argumento para a função.

Você pode refatorar a transação de banco de dados acima para usar withTransaction() assim:

const criarJob = assíncrono (trabalho) => {
const { userEmail, cargo, localização, salário } = trabalho;

// obtém o usuário do banco de dados
const usuário = aguardam userCollection.findOne({ e-mail: usuárioEmail });

// inicia sessão de transação
const sessão = aguardam connection.startSession();

// executa todas as consultas ao banco de dados em um bloco try-catch
tentar {
const transaçãoSucesso = aguardam sessão.comTransação(assíncrono () => {
const newJob = aguardam jobCollection.create(
[
{
título,
localização,
salário,
cartaz: user._id,
},
],
{ sessão }
);

console.log("Criado novo trabalho com sucesso!");
console.log (novoJob[0]);

// adiciona trabalho à lista de usuários de trabalhos postados
const newJobId = newJob[0]._eu ia;
const adicionadoToUser = aguardam userCollection.findByIdAndUpdate(
ID do usuário,
{ $addToSet: { empregos: newJobId } },
{ sessão }
);

console.log("Trabalho adicionado com sucesso à lista de trabalhos do usuário");
console.log (addedToUser);
});

se (transaçãoSucesso) {
console.log("Transação DB realizada com sucesso");
} outro {
console.log("Falha na transação");
}
} pegar (e) {
console.erro (e);
console.log("Falha ao concluir as operações do banco de dados");
} finalmente {
aguardam sessão.endSession();
console.log("Sessão de transação encerrada");
}
};

Isso produziria a mesma saída que a implementação anterior. Você é livre para escolher qual estilo usar ao implementar transações de banco de dados no MongoDB.

Esta implementação não usa o commitTransaction() e abortTransaction() funções. Isso ocorre porque o withTransaction() A função confirma automaticamente as transações bem-sucedidas e aborta as que falharam. A única função que você deve chamar em todos os casos é a sessão.endSession() função.

Implementando transações de banco de dados ACID no MongoDB

As transações de banco de dados são fáceis de usar quando feitas corretamente. Agora você deve entender como as transações do banco de dados funcionam no MongoDB e como você pode implementá-las em aplicativos Node.js.

Para explorar ainda mais a ideia de transações ACID e como elas funcionam no MongoDB, considere criar uma carteira fintech ou um aplicativo de blog.