Læsere som dig hjælper med at støtte MUO. Når du foretager et køb ved hjælp af links på vores websted, kan vi optjene en affiliate-kommission.

Opbygning af en produktionsklar webapplikation kræver, at du sikrer, at den er sikker og skalerbar.

En af de mest afgørende ting at vide om databaser er ACID-princippet, som står for atomicitet, konsistens, isolation og holdbarhed. Relationelle databaser som MySQL understøtter native ACID-transaktioner. Men MongoDB er en NoSQL-database og understøtter ikke ACID-transaktioner som standard.

Som programmør bør du vide, hvordan du introducerer ACID-egenskaber i dine MongoDB-databaser.

Hvad er databasetransaktioner?

En databasetransaktion er en sekvens af databaseforespørgsler eller -operationer, der alle udføres sammen som én enhed for at fuldføre én opgave.

Databasetransaktioner overholder begreberne ACID-egenskaber. Dette er med til at sikre, at der ikke sker ændringer, medmindre alle operationer lykkes. Det sikrer også, at databasen er konsistent.

Syreegenskaberne forklaret

instagram viewer

De fire egenskaber, der udgør ACID-principperne, er:

  • Atomicitet er den egenskab, der konceptualiserer transaktioner som små enheder af et program. Dette indebærer, at alle forespørgsler enten kører med succes eller mislykkes sammen.
  • Konsistens anfører, at databaseregistreringer skal forblive konsistente før og efter hver transaktion.
  • Isolation sikrer, at når flere transaktioner kører samtidigt, påvirker den ene ikke den anden.
  • Holdbarhed fokuserer på systemfejl eller fejl. Det sikrer, at en forpligtet transaktion ikke går tabt i tilfælde af systemfejl. Dette kan involvere teknikker, der er nødvendige for at gendanne data fra en sikkerhedskopi automatisk, når systemet kommer op igen.

Sådan implementeres MongoDB-databasetransaktioner i Node.js ved hjælp af Mongoose

MongoDB er blevet en meget brugt databaseteknologi gennem årene pga dens NoSQL-karakter og fleksibel dokumentbaseret model. Det giver dig også mulighed for bedre at organisere dine data og mere fleksibelt end i SQL eller relationelle databaser.

For at implementere databasetransaktioner i MongoDB kan du overveje et eksempelscenarie på en jobopslagsapplikation, hvor en bruger kan sende, opdatere eller slette et job. Her er et simpelt databaseskemadesign til denne applikation:

For at følge med kræver dette afsnit grundlæggende viden om Node.js-programmering og MongoDB.

Transaktioner understøttes ikke på selvstændige MongoDB-installationer. Du skal bruge en MongoDB replika sæt eller MongoDB sharded klynge for at transaktioner fungerer. Derfor er den nemmeste måde at bruge transaktioner på oprette en cloud-hostet MongoDB-instans (MongoDB Atlas). Som standard er hver Atlas-databaseforekomst et replikasæt eller sharded cluster.

Efter at have konfigureret et fungerende Node.js og MongoDB-projekt, kan du oprette en forbindelse til en Mongo-database i Node.js. Hvis du ikke har gjort det før nu, skal du installere mongoose ved at køre npm installere mongoose i din terminal.

importere mangust fra 'mangust'

lad MONGO_URL = process.env. MONGO_URL || 'din-mongo-database-url';

lade forbindelse;
konst connectDb = asynkron () => {
prøve {
vente mongoose.connect (MONGO_URL, {
useNewUrlParser: rigtigt,
brug UnifiedTopology: rigtigt,
});

console.log("FORBUNDET TIL DATABASE");
forbindelse = mongoose.forbindelse;
} fangst (fejl) {
console.error("DATABASE FORBINDELSE FEJLLET!");
konsol.fejl(fejl.besked);
behandle.Afslut(1); // luk appen, hvis databaseforbindelsen mislykkes
}
};

Du bør gemme forbindelsen i en variabel, så du kan bruge den til at starte en transaktion senere i programmet.

Du kan implementere bruger- og jobsamlingerne som sådan:

konst userSchema = ny mangust. Skema({
navn: Snor,
e-mail: Snor,
job: [mangust. Skema. Typer. ObjectId]
});

konst jobSchema = ny mangust. Skema({
titel: Snor,
Beliggenhed: Snor,
løn: Snor,
plakat: mangust.Skema.Typer.ObjectId
});

const userCollection = mongoose.model('bruger', brugerskema);
const jobCollection = mongoose.model('job', jobSchema);

Du kan skrive en funktion for at tilføje en bruger til databasen sådan her:


konst opretteBruger = asynkron (bruger) => {
konst nyBruger = vente userCollection.create (bruger);
konsol.log("Bruger tilføjet til databasen");
konsol.log (nyBruger);
}

Koden nedenfor demonstrerer funktionen til at oprette et job og tilføje det til dets posters liste over job ved hjælp af en databasetransaktion.


konst skabeJob = asynkron (job) => {
konst { userEmail, title, location, salary } = job;

// få brugeren fra DB
konst bruger = vente userCollection.findOne({ e-mail: brugerE-mail });

// start transaktionssession
konst session = vente forbindelse.startSession();

// kør alle databaseforespørgsler i en try-catch-blok
prøve {
vente session.startTransaction();

// skabe job
konst nytjob = vente jobCollection.create(
[
{
titel,
Beliggenhed,
løn,
plakat: bruger._id,
},
],
{ session }
);
konsol.log("Oprettet ny job med succes!");
konsol.log (nyjob[0]);

// føj job til brugerlisten over udsendte job
konst newJobId = newJob[0]._id;
konst addedToUser = vente userCollection.findByIdAndUpdate(
bruger ID,
{ $addToSet: { job: newJobId } },
{ session }
);

konsol.log("Job blev tilføjet til brugerens jobliste");
konsol.log (addedToUser);

vente session.commitTransaction();

konsol.log("Udført DB-transaktion med succes");
} fangst (e) {
konsol.fejl (e);
konsol.log("Kunnede ikke fuldføre databaseoperationer");
vente session.abortTransaction();
} endelig {
vente session.endSession();
konsol.log("Afsluttet transaktionssession");
}
};

EN skab forespørgsel, der kører i en transaktion, tager normalt ind og returnerer et array. Du kan se dette i koden ovenfor, hvor det opretter nyt job og gemmer dens _id ejendom inyJobId variabel.

Her er en demonstration af, hvordan ovenstående funktioner fungerer:

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

konst mockJob = {
titel: "Salgschef",
sted: "Lagos, Nigeria",
løn: "$40,000",
brugerE-mail: "[email protected]", // e-mail fra den oprettede bruger
};

konst startServer = asynkron () => {
vente connectDb();
vente createUser (mockUser);
vente createJob (mockJob);
};

startServer()
.derefter()
.catch((fejl) => konsol.log (fejl));

Hvis du gemmer denne kode og kører den vha npm start eller den node kommando, skulle det producere et output som dette:

En anden måde at implementere ACID-transaktioner i MongoDB ved hjælp af Mongoose er ved at bruge withTransaction() fungere. Denne tilgang giver ringe fleksibilitet, da den kører alle forespørgsler inde i en tilbagekaldsfunktion, som du sender som et argument til funktionen.

Du kan refaktorisere ovenstående databasetransaktion til brug withTransaction() sådan her:

konst skabeJob = asynkron (job) => {
konst { userEmail, title, location, salary } = job;

// få brugeren fra DB
konst bruger = vente userCollection.findOne({ e-mail: brugerE-mail });

// start transaktionssession
konst session = vente forbindelse.startSession();

// kør alle databaseforespørgsler i en try-catch-blok
prøve {
konst transaktion Succes = vente session.withTransaction(asynkron () => {
konst nytjob = vente jobCollection.create(
[
{
titel,
Beliggenhed,
løn,
plakat: bruger._id,
},
],
{ session }
);

konsol.log("Oprettet ny job med succes!");
konsol.log (nyjob[0]);

// føj job til brugerlisten over udsendte job
konst newJobId = newJob[0]._id;
konst addedToUser = vente userCollection.findByIdAndUpdate(
bruger ID,
{ $addToSet: { job: newJobId } },
{ session }
);

konsol.log("Job blev tilføjet til brugerens jobliste");
konsol.log (addedToUser);
});

hvis (transaktionssucces) {
konsol.log("Udført DB-transaktion med succes");
} andet {
konsol.log("Transaktion mislykkedes");
}
} fangst (e) {
konsol.fejl (e);
konsol.log("Kunnede ikke fuldføre databaseoperationer");
} endelig {
vente session.endSession();
konsol.log("Afsluttet transaktionssession");
}
};

Dette ville producere det samme output som den tidligere implementering. Du kan frit vælge, hvilken stil du vil bruge, når du implementerer databasetransaktioner i MongoDB.

Denne implementering bruger ikke commitTransaction() og abortTransaction() funktioner. Dette er fordi withTransaction() funktion begår automatisk vellykkede transaktioner og afbryder mislykkede. Den eneste funktion, du bør kalde i alle tilfælde, er session.endSession() fungere.

Implementering af ACID-databasetransaktioner i MongoDB

Databasetransaktioner er nemme at bruge, når de udføres korrekt. Du bør nu forstå, hvordan databasetransaktioner fungerer i MongoDB, og hvordan du kan implementere dem i Node.js-applikationer.

For yderligere at udforske ideen om ACID-transaktioner, og hvordan de fungerer i MongoDB, kan du overveje at bygge en fintech-pung eller blogging-applikation.