I lettori come te aiutano a sostenere MUO. Quando effettui un acquisto utilizzando i link sul nostro sito, potremmo guadagnare una commissione di affiliazione.

La creazione di un'applicazione Web pronta per la produzione richiede di garantire che sia sicura e scalabile.

Una delle cose più importanti da sapere sui database è il principio ACID che sta per atomicità, coerenza, isolamento e durabilità. I database relazionali come MySQL supportano nativamente le transazioni ACID. Ma MongoDB è un database NoSQL e non supporta le transazioni ACID per impostazione predefinita.

Come programmatore, dovresti sapere come introdurre le proprietà ACID nei tuoi database MongoDB.

Cosa sono le transazioni di database?

Una transazione di database è una sequenza di query o operazioni di database che vengono eseguite tutte insieme come un'unica unità per completare un'attività.

Le transazioni di database aderiscono ai concetti delle caratteristiche ACID. Ciò consente di garantire che non si verifichino modifiche a meno che tutte le operazioni non abbiano esito positivo. Garantisce inoltre che il database sia coerente.

instagram viewer

Spiegazione delle proprietà ACID

Le quattro proprietà che compongono i principi ACID sono:

  • Atomicita è la proprietà che concettualizza le transazioni come piccole unità di un programma. Ciò implica che tutte le query vengono eseguite correttamente o falliscono insieme.
  • Consistenza afferma che i record del database devono rimanere coerenti prima e dopo ogni transazione.
  • Isolamento garantisce che, quando più transazioni vengono eseguite contemporaneamente, una non influisca sull'altra.
  • Durata si concentra su guasti o guasti del sistema. Garantisce che una transazione di cui è stato eseguito il commit non venga persa in caso di errore del sistema. Ciò può comportare tecniche necessarie per ripristinare automaticamente i dati da un backup una volta che il sistema si riavvia.

Come implementare le transazioni del database MongoDB in Node.js utilizzando Mongoose

MongoDB è diventata una tecnologia di database ampiamente utilizzata nel corso degli anni a causa di la sua natura NoSQL e flessibile modello basato su documenti. Ti offre anche la possibilità di organizzare meglio i tuoi dati e in modo più flessibile rispetto a SQL o ai database relazionali.

Per implementare transazioni di database in MongoDB, puoi considerare uno scenario di esempio su un'applicazione di annunci di lavoro in cui un utente può pubblicare, aggiornare o eliminare un lavoro. Ecco un semplice progetto di schema di database per questa applicazione:

Per proseguire, questa sezione richiede una conoscenza di base della programmazione Node.js e MongoDB.

Le transazioni non sono supportate nelle installazioni MongoDB autonome. Dovrai usare un Set di repliche MongoDB O Cluster frammentato MongoDB affinché le transazioni funzionino. Pertanto, il modo più semplice per utilizzare le transazioni è creare un'istanza MongoDB ospitata nel cloud (Atlante MongoDB). Per impostazione predefinita, ogni istanza del database Atlas è un set di repliche o un cluster partizionato.

Dopo aver impostato un progetto Node.js e MongoDB funzionante, puoi configurare una connessione a un database Mongo in Node.js. Se non l'hai già fatto, installa mangusta eseguendo npm installa mangusta nel tuo terminale.

importare mangusta da 'mangusta'

let MONGO_URL = process.env. MONGO_URL || 'tuo-mongo-database-url';

permettere connessione;
cost connectDb = asincrono () => {
Tentativo {
aspetta mongoose.connect (MONGO_URL, {
useNewUrlParser: VERO,
usaTopologia unificata: VERO,
});

console.log("CONNESSO AL DATABASE");
connessione = mangusta.connessione;
} presa (errare) {
console.errore("CONNESSIONE DATABASE FALLITA!");
consolare.errore(errare.Messaggio);
processi.Uscita(1); // chiude l'app se la connessione al database fallisce
}
};

È necessario memorizzare la connessione in una variabile in modo da poterla utilizzare per avviare una transazione successivamente nel programma.

Puoi implementare le raccolte di utenti e lavori in questo modo:

cost utenteSchema = nuovo mangusta. Schema({
nome: Corda,
e-mail: Corda,
lavori: [mangusta. Schema. Tipi. IDoggetto]
});

cost jobSchema = nuovo mangusta. Schema({
titolo: Corda,
posizione: Corda,
stipendio: Corda,
manifesto: mangusta.Schema.Tipi.Idoggetto
});

const userCollection = mongoose.model('utente', userSchema);
const jobCollection = mongoose.model('lavoro', jobSchema);

Puoi scrivere una funzione per aggiungere un utente al database in questo modo:


cost createUser = asincrono (utente) => {
cost nuovoutente = aspetta userCollection.create (utente);
consolare.log("Utente aggiunto al database");
consolare.log (nuovoutente);
}

Il codice seguente mostra la funzione per creare un lavoro e aggiungerlo all'elenco dei lavori del poster utilizzando una transazione di database.


cost createJob = asincrono (lavoro) => {
cost { userEmail, titolo, posizione, stipendio } = lavoro;

// recupera l'utente dal DB
cost utente = aspetta userCollection.findOne({ e-mail: userEmail });

// avvia la sessione di transazione
cost sessione = aspetta connessione.startSession();

// esegue tutte le query del database in un blocco try-catch
Tentativo {
aspetta sessione.startTransaction();

// crea lavoro
cost nuovolavoro = aspetta jobCollection.create(
[
{
titolo,
posizione,
stipendio,
inserzionista: user._id,
},
],
{ sessione }
);
consolare.log("Creato nuovo lavoro con successo!");
consolare.log (nuovolavoro[0]);

// aggiunge il lavoro all'elenco degli utenti dei lavori pubblicati
cost newJobId = newJob[0]._id;
cost aggiuntoAUtente = aspetta userCollection.findByIdAndUpdate(
ID utente,
{ $addToSet: { lavori: newJobId } },
{ sessione }
);

consolare.log("Lavoro aggiunto con successo alla lista dei lavori dell'utente");
consolare.log (addedToUser);

aspetta sessione.commitTransaction();

consolare.log("Transazione DB eseguita con successo");
} presa (e) {
consolare.errore (e);
consolare.log("Impossibile completare le operazioni del database");
aspetta sessione.abortTransaction();
} Finalmente {
aspetta sessione.endSession();
consolare.log("Sessione transazione terminata");
}
};

UN creare la query che viene eseguita in una transazione di solito accetta e restituisce un array. Puoi vederlo nel codice sopra dove crea nuovo lavoro e memorizza il suo _id proprietà nelnewJobId variabile.

Ecco una dimostrazione di come funzionano le funzioni di cui sopra:

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

cost lavoro fittizio = {
titolo: "Responsabile vendite",
luogo: "Lagos, Nigeria",
stipendio: "$40,000",
userEmail: "[email protected]", // email dell'utente creato
};

cost startServer = asincrono () => {
aspetta connectDb();
aspetta createUser (utente simulato);
aspetta createJob (mockJob);
};

avviaServer()
.Poi()
.catch((err) => consolare.log (err));

Se salvi questo codice e lo esegui usando inizio npm o il nodo comando, dovrebbe produrre un output come questo:

Un altro modo per implementare le transazioni ACID in MongoDB utilizzando Mongoose è utilizzare il file conTransazione() funzione. Questo approccio offre poca flessibilità in quanto esegue tutte le query all'interno di una funzione di callback passata come argomento alla funzione.

È possibile eseguire il refactoring della transazione del database di cui sopra da utilizzare conTransazione() come questo:

cost createJob = asincrono (lavoro) => {
cost { userEmail, titolo, posizione, stipendio } = lavoro;

// recupera l'utente dal DB
cost utente = aspetta userCollection.findOne({ e-mail: userEmail });

// avvia la sessione di transazione
cost sessione = aspetta connessione.startSession();

// esegue tutte le query del database in un blocco try-catch
Tentativo {
cost transazionesuccesso = aspetta sessione.conTransazione(asincrono () => {
cost nuovolavoro = aspetta jobCollection.create(
[
{
titolo,
posizione,
stipendio,
inserzionista: user._id,
},
],
{ sessione }
);

consolare.log("Creato nuovo lavoro con successo!");
consolare.log (nuovolavoro[0]);

// aggiunge il lavoro all'elenco degli utenti dei lavori pubblicati
cost newJobId = newJob[0]._id;
cost aggiuntoAUtente = aspetta userCollection.findByIdAndUpdate(
ID utente,
{ $addToSet: { lavori: newJobId } },
{ sessione }
);

consolare.log("Lavoro aggiunto con successo alla lista dei lavori dell'utente");
consolare.log (addedToUser);
});

Se (transazione riuscita) {
consolare.log("Transazione DB eseguita con successo");
} altro {
consolare.log("Transazione fallita");
}
} presa (e) {
consolare.errore (e);
consolare.log("Impossibile completare le operazioni del database");
} Finalmente {
aspetta sessione.endSession();
consolare.log("Sessione transazione terminata");
}
};

Ciò produrrebbe lo stesso output dell'implementazione precedente. Sei libero di scegliere quale stile utilizzare durante l'implementazione delle transazioni di database in MongoDB.

Questa implementazione non utilizza il commitTransazione() E abortTransaction() funzioni. Questo perché il conTransazione() la funzione esegue automaticamente il commit delle transazioni riuscite e interrompe quelle fallite. L'unica funzione che dovresti chiamare in tutti i casi è the sessione.endSession() funzione.

Implementazione delle transazioni del database ACID in MongoDB

Le transazioni del database sono facili da usare se eseguite correttamente. Ora dovresti capire come funzionano le transazioni del database in MongoDB e come puoi implementarle nelle applicazioni Node.js.

Per esplorare ulteriormente l'idea delle transazioni ACID e il modo in cui funzionano in MongoDB, prendi in considerazione la creazione di un portafoglio fintech o di un'applicazione di blog.