Čtenáři jako vy pomáhají podporovat MUO. Když provedete nákup pomocí odkazů na našich stránkách, můžeme získat provizi přidružené společnosti.

Vytvoření webové aplikace připravené na provoz vyžaduje, abyste zajistili, že je bezpečná a škálovatelná.

Jednou z nejdůležitějších věcí, které byste měli vědět o databázích, je princip ACID, který znamená atomicitu, konzistenci, izolaci a trvanlivost. Relační databáze jako MySQL nativně podporují transakce ACID. Ale MongoDB je databáze NoSQL a ve výchozím nastavení nepodporuje transakce ACID.

Jako programátor byste měli vědět, jak zavést vlastnosti ACID do vašich databází MongoDB.

Co jsou databázové transakce?

Databázová transakce je posloupnost databázových dotazů nebo operací, které se všechny provádějí společně jako jedna jednotka za účelem dokončení jednoho úkolu.

Databázové transakce dodržují koncepty ACID charakteristik. To pomáhá zajistit, že nedojde k žádným změnám, pokud nebudou všechny operace úspěšné. Zajišťuje také konzistentnost databáze.

instagram viewer

Vysvětlení vlastností ACID

Čtyři vlastnosti, které tvoří principy ACID, jsou:

  • Atomicita je vlastnost, která konceptualizuje transakce jako malé jednotky programu. To znamená, že všechny dotazy proběhnou úspěšně nebo selžou společně.
  • Konzistence uvádí, že databázové záznamy musí zůstat konzistentní před a po každé transakci.
  • Izolace zajišťuje, že když běží více transakcí současně, jedna neovlivní druhou.
  • Trvanlivost se zaměřuje na systémové poruchy nebo závady. Zajišťuje, že se potvrzená transakce neztratí v případě selhání systému. To může zahrnovat techniky nezbytné k automatické obnově dat ze zálohy, jakmile se systém znovu spustí.

Jak implementovat databázové transakce MongoDB v Node.js pomocí Mongoose

MongoDB se v průběhu let stala široce používanou databázovou technologií jeho povaha NoSQL a flexibilní model založený na dokumentech. Nabízí vám také možnost lépe organizovat data a flexibilněji než v SQL nebo relačních databázích.

Chcete-li implementovat databázové transakce v MongoDB, můžete zvážit ukázkový scénář v aplikaci se seznamem úloh, kde může uživatel odeslat, aktualizovat nebo odstranit úlohu. Zde je jednoduchý návrh schématu databáze pro tuto aplikaci:

Chcete-li pokračovat, tato část vyžaduje základní znalosti programování Node.js a MongoDB.

Transakce nejsou podporovány na samostatných instalacích MongoDB. Budete muset použít a Sada replik MongoDB nebo MongoDB sharded cluster aby transakce fungovaly. Nejjednodušší způsob použití transakcí je proto vytvořit instanci MongoDB hostovanou v cloudu (Atlas MongoDB). Ve výchozím nastavení je každá instance databáze Atlas sadou replik nebo sdíleným clusterem.

Po nastavení funkčního projektu Node.js a MongoDB můžete nastavit připojení k databázi Mongo v Node.js. Pokud jste tak dosud neučinili, nainstalujte si mongoose spuštěním npm nainstalovat mongoose ve vašem terminálu.

import mangusta z 'mangusta'

nechť MONGO_URL = process.env. MONGO_URL || 'your-mongo-database-url';

nechat spojení;
konst connectDb = asynchronní () => {
Snaž se {
čekat mongoose.connect (MONGO_URL, {
useNewUrlParser: skutečný,
useUnifiedTopology: skutečný,
});

console.log("PŘIPOJENO K DATABÁZI");
spojení = mangoose.spojení;
} chytit (chyba) {
console.error("PŘIPOJENÍ K DATABÁZI SE NEZDALO!");
řídicí panel.chyba(chybovat.zpráva);
proces.výstup(1); // zavře aplikaci, pokud selže připojení k databázi
}
};

Měli byste uložit připojení do proměnné, abyste ji mohli použít k zahájení transakce později v programu.

Kolekce uživatelů a úloh můžete implementovat takto:

konst userSchema = Nový mangusta. Schéma({
název: Tětiva,
e-mailem: Tětiva,
pracovní místa: [mangusta. Schéma. Typy. ObjectId]
});

konst jobSchema = Nový mangusta. Schéma({
titul: Tětiva,
umístění: Tětiva,
plat: Tětiva,
plakát: mangusta.Schéma.Typy.ObjectId
});

const userCollection = mongoose.model('uživatel', userSchema);
const jobCollection = mongoose.model('práce', jobSchema);

Můžete napsat funkci pro přidání uživatele do databáze takto:


konst createUser = asynchronní (uživatel) => {
konst nový uživatel = čekat userCollection.create (uživatel);
řídicí panel.log("Uživatel přidán do databáze");
řídicí panel.log (novýUživatel);
}

Níže uvedený kód demonstruje funkci vytvoření úlohy a její přidání do seznamu úloh jejího plakátu pomocí databázové transakce.


konst vytvořitJob = asynchronní (zaměstnání) => {
konst { userEmail, title, location, plat } = job;

// získat uživatele z DB
konst uživatel = čekat userCollection.findOne({ e-mailem: userEmail });

// zahájení relace transakce
konst relace = čekat connection.startSession();

// spusťte všechny databázové dotazy v bloku try-catch
Snaž se {
čekat session.startTransaction();

// vytvořit úlohu
konst nová práce = čekat jobCollection.create(
[
{
titul,
umístění,
plat,
plakát: user._id,
},
],
{ zasedání }
);
řídicí panel.log("Vytvořeno Nový práce úspěšně!");
řídicí panel.log (newJob[0]);

// přidání úlohy do seznamu zadaných úloh uživatelů
konst newJobId = newJob[0]._id;
konst addedToUser = čekat userCollection.findByIdAndUpdate(
uživatelské ID,
{ $addToSet: { pracovní místa: newJobId } },
{ zasedání }
);

řídicí panel.log("Úloha byla úspěšně přidána do seznamu úloh uživatele");
řídicí panel.log (addedToUser);

čekat session.commitTransaction();

řídicí panel.log("Úspěšně provedena DB transakce");
} chytit (e) {
řídicí panel.chyba (e);
řídicí panel.log("Nepodařilo se dokončit operace databáze");
čekat session.abortTransaction();
} Konečně {
čekat session.endSession();
řídicí panel.log("Ukončená relace transakce");
}
};

A vytvořit dotaz, který běží v transakci, obvykle přijímá a vrací pole. Můžete to vidět v kódu výše, kde se vytváří nová práce a ukládá jeho _id nemovitost vnewJobId variabilní.

Zde je ukázka toho, jak fungují výše uvedené funkce:

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

konst mockJob = {
název: "Manažer prodeje",
místo: "Lagos, Nigérie",
plat: "$40,000",
userEmail: "[email protected]", // email vytvořeného uživatele
};

konst startServer = asynchronní () => {
čekat connectDb();
čekat createUser (mockUser);
čekat createJob (mockJob);
};

startServer()
.pak()
.catch((chyba) => řídicí panel.log (chyba));

Pokud uložíte tento kód a spustíte jej pomocí npm start nebo uzel příkaz, měl by vytvořit výstup takto:

Dalším způsobem implementace transakcí ACID v MongoDB pomocí Mongoose je použití withTransaction() funkce. Tento přístup poskytuje malou flexibilitu, protože spouští všechny dotazy uvnitř funkce zpětného volání, kterou předáte funkci jako argument.

Můžete refaktorovat výše uvedenou databázovou transakci k použití withTransaction() takhle:

konst vytvořitJob = asynchronní (zaměstnání) => {
konst { userEmail, title, location, plat } = job;

// získat uživatele z DB
konst uživatel = čekat userCollection.findOne({ e-mailem: userEmail });

// zahájení relace transakce
konst relace = čekat connection.startSession();

// spusťte všechny databázové dotazy v bloku try-catch
Snaž se {
konst transakceÚspěch = čekat session.withTransaction(asynchronní () => {
konst nová práce = čekat jobCollection.create(
[
{
titul,
umístění,
plat,
plakát: user._id,
},
],
{ zasedání }
);

řídicí panel.log("Vytvořeno Nový práce úspěšně!");
řídicí panel.log (newJob[0]);

// přidání úlohy do seznamu zadaných úloh uživatelů
konst newJobId = newJob[0]._id;
konst addedToUser = čekat userCollection.findByIdAndUpdate(
uživatelské ID,
{ $addToSet: { pracovní místa: newJobId } },
{ zasedání }
);

řídicí panel.log("Úloha byla úspěšně přidána do seznamu úloh uživatele");
řídicí panel.log (addedToUser);
});

-li (transactionSuccess) {
řídicí panel.log("Úspěšně provedena DB transakce");
} jiný {
řídicí panel.log("Transakce se nezdařila");
}
} chytit (e) {
řídicí panel.chyba (e);
řídicí panel.log("Nepodařilo se dokončit operace databáze");
} Konečně {
čekat session.endSession();
řídicí panel.log("Ukončená relace transakce");
}
};

To by přineslo stejný výstup jako předchozí implementace. Můžete si vybrat, který styl použít při implementaci databázových transakcí v MongoDB.

Tato implementace nepoužívá commitTransaction() a abortTransaction() funkcí. Je to proto, že withTransaction() funkce automaticky potvrdí úspěšné transakce a zruší ty neúspěšné. Jediná funkce, kterou byste měli volat ve všech případech, je session.endSession() funkce.

Implementace ACID databázových transakcí v MongoDB

Databázové transakce jsou snadno použitelné, pokud jsou provedeny správně. Nyní byste měli pochopit, jak databázové transakce fungují v MongoDB a jak je můžete implementovat do aplikací Node.js.

Chcete-li dále prozkoumat myšlenku transakcí ACID a jejich fungování v MongoDB, zvažte vytvoření fintech peněženky nebo blogovací aplikace.