Läsare som du hjälper till att stödja MUO. När du gör ett köp med hjälp av länkar på vår webbplats kan vi tjäna en affiliate-provision.

Att bygga en produktionsklar webbapplikation kräver att du ser till att den är säker och skalbar.

En av de mest avgörande sakerna att veta om databaser är ACID-principen som står för atomicitet, konsistens, isolering och hållbarhet. Relationsdatabaser som MySQL stöder ACID-transaktioner inbyggt. Men MongoDB är en NoSQL-databas och stöder inte ACID-transaktioner som standard.

Som programmerare bör du veta hur du introducerar ACID-egenskaper i dina MongoDB-databaser.

Vad är databastransaktioner?

En databastransaktion är en sekvens av databasfrågor eller operationer som alla körs tillsammans som en enhet för att slutföra en uppgift.

Databastransaktioner följer begreppen ACID-egenskaper. Detta hjälper till att säkerställa att inga förändringar sker om inte alla operationer är framgångsrika. Det säkerställer också att databasen är konsekvent.

ACID-egenskaperna förklaras

instagram viewer

De fyra egenskaperna som utgör ACID-principerna är:

  • Atomicitet är egenskapen som konceptualiserar transaktioner som små enheter i ett program. Detta innebär att alla frågor antingen körs framgångsrikt eller misslyckas tillsammans.
  • Konsistens anger att databasposter måste förbli konsekventa före och efter varje transaktion.
  • Isolering säkerställer att, när flera transaktioner körs samtidigt, den ena inte påverkar den andra.
  • Varaktighet fokuserar på systemfel eller fel. Det säkerställer att en genomförd transaktion inte går förlorad i händelse av ett systemfel. Detta kan innebära tekniker som krävs för att automatiskt återställa data från en säkerhetskopia när systemet kommer upp igen.

Hur man implementerar MongoDB-databastransaktioner i Node.js med Mongoose

MongoDB har blivit en mycket använd databasteknik genom åren på grund av dess NoSQL-karaktär och flexibel dokumentbaserad modell. Det ger dig också möjligheten att bättre organisera dina data och mer flexibelt än i SQL eller relationsdatabaser.

För att implementera databastransaktioner i MongoDB kan du överväga ett exempelscenario på en jobbannonsapplikation där en användare kan lägga upp, uppdatera eller ta bort ett jobb. Här är en enkel databasschemadesign för denna applikation:

För att följa med kräver detta avsnitt grundläggande kunskaper om Node.js-programmering och MongoDB.

Transaktioner stöds inte på fristående MongoDB-installationer. Du måste använda en MongoDB replika set eller MongoDB fragmenterat kluster för att transaktioner ska fungera. Därför är det enklaste sättet att använda transaktioner att skapa en molnvärd MongoDB-instans (MongoDB Atlas). Som standard är varje Atlas-databasinstans en replikuppsättning eller ett fragmenterat kluster.

Efter att ha ställt in ett fungerande Node.js- och MongoDB-projekt kan du skapa en anslutning till en Mongo-databas i Node.js. Om du inte har gjort det tidigare, installera mongoose genom att köra npm installera mongoose i din terminal.

importera mungo från 'mungo'

låt MONGO_URL = process.env. MONGO_URL || 'din-mongo-databas-url';

låta förbindelse;
konst connectDb = asynkron () => {
Prova {
vänta mongoose.connect (MONGO_URL, {
useNewUrlParser: Sann,
använd UnifiedTopology: Sann,
});

console.log("ANSLUTEN TILL DATABAS");
anslutning = mongoose.connection;
} fånga (fel) {
console.error("DATABASANSLUTNING MISSLYCKades!");
trösta.fel(fela.meddelande);
bearbeta.utgång(1); // stäng appen om databasanslutningen misslyckas
}
};

Du bör lagra anslutningen i en variabel så att du kan använda den för att initiera en transaktion senare i programmet.

Du kan implementera användar- och jobbsamlingarna så här:

konst userSchema = ny mungo. Schema({
namn: Sträng,
e-post: Sträng,
jobb: [mungo. Schema. Typer. ObjectId]
});

konst jobbschema = ny mungo. Schema({
titel: Sträng,
plats: Sträng,
lön: Sträng,
affisch: mungo.Schema.Typer.ObjectId
});

const userCollection = mongoose.model('användare', userSchema);
const jobCollection = mongoose.model('jobb', jobSchema);

Du kan skriva en funktion för att lägga till en användare till databasen så här:


konst createUser = asynkron (användare) => {
konst nyAnvändare = vänta userCollection.create (användare);
trösta.log("Användare har lagts till i databasen");
trösta.log (nyanvändare);
}

Koden nedan visar funktionen för att skapa ett jobb och lägga till det i dess posters lista över jobb med hjälp av en databastransaktion.


konst skapaJob = asynkron (jobb) => {
konst { userEmail, title, location, salary } = jobb;

// hämta användaren från DB
konst användare = vänta userCollection.findOne({ e-post: userEmail });

// starta transaktionssessionen
konst session = vänta connection.startSession();

// kör alla databasfrågor i ett try-catch-block
Prova {
vänta session.startTransaction();

// skapa jobb
konst nytt jobb = vänta jobCollection.create(
[
{
titel,
plats,
lön,
poster: user._id,
},
],
{ session }
);
trösta.log("Skapat ny jobb framgångsrikt!");
trösta.log (newJob[0]);

// lägg till jobb i användarlistan över publicerade jobb
konst newJobId = newJob[0]._id;
konst addedToUser = vänta userCollection.findByIdAndUpdate(
användar ID,
{ $addToSet: { jobb: newJobId } },
{ session }
);

trösta.log("Lagde jobb till användarens jobblista");
trösta.log (addedToUser);

vänta session.commitTransaction();

trösta.log("Uppförd DB-transaktion framgångsrikt");
} fånga (e) {
trösta.fel (e);
trösta.log("Det gick inte att slutföra databasoperationer");
vänta session.abortTransaction();
} till sist {
vänta session.endSession();
trösta.log("Avslutad transaktionssession");
}
};

A skapa fråga som körs i en transaktion tar vanligtvis in och returnerar en array. Du kan se detta i koden ovan där det skapas nya jobb och lagrar dess _id egendom inewJobId variabel.

Här är en demonstration av hur ovanstående funktioner fungerar:

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

konst mockJob = {
title: "Säljchef",
plats: "Lagos, Nigeria",
lön: "$40,000",
userEmail: "[email protected]", // e-post för den skapade användaren
};

konst startServer = asynkron () => {
vänta connectDb();
vänta createUser (mockUser);
vänta createJob (mockJob);
};

startServer()
.sedan()
.catch((fel) => trösta.log (fel));

Om du sparar den här koden och kör den med npm start eller den nod kommandot bör det producera en utdata så här:

Ett annat sätt att implementera ACID-transaktioner i MongoDB med Mongoose är att använda withTransaction() fungera. Detta tillvägagångssätt ger liten flexibilitet eftersom det kör alla frågor i en återuppringningsfunktion som du skickar som ett argument till funktionen.

Du kan omfaktorisera ovanstående databastransaktion för att använda withTransaction() så här:

konst skapaJob = asynkron (jobb) => {
konst { userEmail, title, location, salary } = jobb;

// hämta användaren från DB
konst användare = vänta userCollection.findOne({ e-post: userEmail });

// starta transaktionssessionen
konst session = vänta connection.startSession();

// kör alla databasfrågor i ett try-catch-block
Prova {
konst transaktion Framgång = vänta session.withTransaction(asynkron () => {
konst nytt jobb = vänta jobCollection.create(
[
{
titel,
plats,
lön,
poster: user._id,
},
],
{ session }
);

trösta.log("Skapat ny jobb framgångsrikt!");
trösta.log (newJob[0]);

// lägg till jobb i användarlistan över publicerade jobb
konst newJobId = newJob[0]._id;
konst addedToUser = vänta userCollection.findByIdAndUpdate(
användar ID,
{ $addToSet: { jobb: newJobId } },
{ session }
);

trösta.log("Lagde jobb till användarens jobblista");
trösta.log (addedToUser);
});

om (transaktionsframgång) {
trösta.log("Uppförd DB-transaktion framgångsrikt");
} annan {
trösta.log("Transaktion misslyckades");
}
} fånga (e) {
trösta.fel (e);
trösta.log("Det gick inte att slutföra databasoperationer");
} till sist {
vänta session.endSession();
trösta.log("Avslutad transaktionssession");
}
};

Detta skulle ge samma resultat som den tidigare implementeringen. Du är fri att välja vilken stil du ska använda när du implementerar databastransaktioner i MongoDB.

Denna implementering använder inte commitTransaction() och abortTransaction() funktioner. Detta beror på att withTransaction() funktionen begår automatiskt framgångsrika transaktioner och avbryter misslyckade. Den enda funktion som du bör anropa i alla fall är session.endSession() fungera.

Implementering av ACID-databastransaktioner i MongoDB

Databastransaktioner är lätta att använda när de görs på rätt sätt. Du bör nu förstå hur databastransaktioner fungerar i MongoDB och hur du kan implementera dem i Node.js-applikationer.

För att ytterligare utforska idén med ACID-transaktioner och hur de fungerar i MongoDB, överväg att bygga en fintech-plånbok eller bloggapplikation.