Cititorii ca tine ajută la sprijinirea MUO. Când efectuați o achiziție folosind link-uri de pe site-ul nostru, este posibil să câștigăm un comision de afiliat.
Construirea unei aplicații web pregătită pentru producție necesită să vă asigurați că este sigură și scalabilă.
Unul dintre cele mai importante lucruri de știut despre bazele de date este principiul ACID, care reprezintă atomicitate, consistență, izolare și durabilitate. Bazele de date relaționale precum MySQL acceptă tranzacțiile ACID în mod nativ. Dar MongoDB este o bază de date NoSQL și nu acceptă tranzacțiile ACID în mod implicit.
Ca programator, ar trebui să știți cum să introduceți proprietățile ACID în bazele de date MongoDB.
Ce sunt tranzacțiile cu baze de date?
O tranzacție de bază de date este o secvență de interogări sau operații de bază de date care se execută toate împreună ca o singură unitate pentru a finaliza o sarcină.
Tranzacțiile cu baze de date aderă la conceptele de caracteristici ACID. Acest lucru vă ajută să vă asigurați că nu apar modificări decât dacă toate operațiunile au succes. De asemenea, asigură consecvența bazei de date.
Proprietățile ACID explicate
Cele patru proprietăți care compun principiile ACID sunt:
- Atomicitatea este proprietatea care conceptualizează tranzacțiile ca unități mici ale unui program. Aceasta înseamnă că toate interogările fie rulează cu succes, fie eșuează împreună.
- Consecvență afirmă că înregistrările bazei de date trebuie să rămână consistente înainte și după fiecare tranzacție.
- Izolare asigură că, atunci când mai multe tranzacții rulează simultan, una nu o afectează pe cealaltă.
- Durabilitate se concentrează pe defecțiuni sau defecțiuni ale sistemului. Acesta asigură că o tranzacție angajată nu este pierdută în cazul unei defecțiuni a sistemului. Acest lucru poate implica tehnici necesare pentru a restaura automat datele dintr-o copie de rezervă odată ce sistemul revine.
Cum să implementați tranzacțiile cu baze de date MongoDB în Node.js folosind Mongoose
MongoDB a devenit o tehnologie de baze de date utilizată pe scară largă de-a lungul anilor datorită natura sa NoSQL și model flexibil bazat pe documente. De asemenea, vă oferă posibilitatea de a vă organiza mai bine datele și mai flexibil decât în bazele de date SQL sau relaționale.
Pentru a implementa tranzacții de baze de date în MongoDB, puteți lua în considerare un exemplu de scenariu pe o aplicație de listare de locuri de muncă în care un utilizator poate posta, actualiza sau șterge un job. Iată un design simplu de schemă a bazei de date pentru această aplicație:
Pentru a continua, această secțiune necesită cunoștințe de bază despre programarea Node.js și MongoDB.
Tranzacțiile nu sunt acceptate pe instalările autonome MongoDB. Va trebui să utilizați un Set de replică MongoDB sau Cluster fragmentat MongoDB pentru ca tranzacțiile să funcționeze. Prin urmare, cel mai simplu mod de a utiliza tranzacțiile este să creați o instanță MongoDB găzduită în cloud (MongoDB Atlas). În mod implicit, fiecare instanță de bază de date Atlas este un set de replică sau un cluster fragmentat.
După ce ați configurat un proiect funcțional Node.js și MongoDB, puteți configura o conexiune la o bază de date Mongo în Node.js. Dacă nu ați făcut-o până acum, instalați mangusta rulând npm instalează mangusta în terminalul dvs.
import mangustă din 'mangustă'
lasă MONGO_URL = process.env. MONGO_URL || 'your-mongo-database-url';
lăsa conexiune;
const connectDb = asincron () => {
încerca {
asteapta mongoose.connect (MONGO_URL, {
useNewUrlParser: Adevărat,
useUnifiedTopology: Adevărat,
});
console.log("CONECTAT LA BAZĂ DE DATE");
connection = mangusta.connection;
} captură (eroare) {
console.error("CONEXIUNEA BAZEI DE DATE EŞECTE!");
consolă.eroare(a greșit.mesaj);
proces.Ieșire(1); // închide aplicația dacă conexiunea la baza de date eșuează
}
};
Ar trebui să stocați conexiunea într-o variabilă, astfel încât să o puteți utiliza pentru a iniția o tranzacție mai târziu în program.
Puteți implementa colecțiile de utilizatori și locuri de muncă astfel:
const userSchema = nou mangustă. Schemă({
Nume: Şir,
e-mail: Şir,
locuri de munca: [mangustă. Schemă. Tipuri. ObjectId]
});const jobSchema = nou mangustă. Schemă({
titlu: Şir,
Locație: Şir,
salariu: Şir,
poster: mangustă.Schemă.Tipuri.ObjectId
});
const userCollection = mangoose.model('utilizator', userSchema);
const jobCollection = mangoose.model('loc de munca', JobSchema);
Puteți scrie o funcție pentru a adăuga un utilizator la baza de date astfel:
const createUser = asincron (utilizator) => {
const newUser = asteapta userCollection.create (utilizator);
consolă.log(„Utilizatorul adăugat la baza de date”);
consolă.log (utilizator nou);
}
Codul de mai jos demonstrează funcția de a crea o muncă și de a o adăuga la lista de locuri de muncă a afișului său folosind o tranzacție de bază de date.
const createJob = asincron (loc de muncă) => {
const { userEmail, titlu, locație, salariu } = job;// obțineți utilizatorul din DB
const utilizator = asteapta userCollection.findOne({ e-mail: userEmail });// începe sesiunea de tranzacție
const sesiune = asteapta connection.startSession();// rulează toate interogările bazei de date într-un bloc try-catch
încerca {
asteapta session.startTransaction();// creează locuri de muncă
const job nou = asteapta jobCollection.create(
[
{
titlu,
Locație,
salariu,
poster: user._id,
},
],
{ sesiune }
);
consolă.log("Creat nou treaba cu succes!");
consolă.log (newJob[0]);// adaugă job la lista utilizatorilor de joburi postate
const newJobId = newJob[0]._id;
const addedToUser = asteapta userCollection.findByIdAndUpdate(
ID-ul de utilizator,
{ $addToSet: { locuri de munca: newJobId } },
{ sesiune }
);consolă.log("Slujbă adăugată cu succes la lista de locuri de muncă a utilizatorului");
consolă.log (addedToUser);asteapta session.commitTransaction();
consolă.log("Tranzacție DB efectuată cu succes");
} captură (e) {
consolă.eroare (e);
consolă.log(„Nu s-au finalizat operațiunile cu baza de date”);
asteapta session.abortTransaction();
} in cele din urma {
asteapta session.endSession();
consolă.log(„Sesiunea tranzacției încheiată”);
}
};
A crea interogarea care rulează într-o tranzacție de obicei preia și returnează o matrice. Puteți vedea acest lucru în codul de mai sus unde se creează nou loc de muncă și își stochează _id proprietate înnewJobId variabil.
Iată o demonstrație a modului în care funcționează funcțiile de mai sus:
const mockUser = {
nume: "Timmy Omolana",
e-mail: „[email protected]”,
};const mockJob = {
titlu: „Director de vânzări”,
locație: "Lagos, Nigeria",
salariu: „$40,000",
userEmail: „[email protected]”, // e-mailul utilizatorului creat
};const startServer = asincron () => {
asteapta connectDb();
asteapta createUser (mockUser);
asteapta createJob (mockJob);
};
startServer()
.apoi()
.catch((err) => consolă.log (err));
Dacă salvați acest cod și îl rulați folosind npm start sau nodul comandă, ar trebui să producă o ieșire ca aceasta:
O altă modalitate de implementare a tranzacțiilor ACID în MongoDB folosind Mongoose este utilizarea withTransaction() funcţie. Această abordare oferă puțină flexibilitate, deoarece rulează toate interogările într-o funcție de apel invers pe care o transmiteți ca argument funcției.
Puteți refactoriza tranzacția din baza de date de mai sus pentru a o utiliza withTransaction() ca aceasta:
const createJob = asincron (loc de muncă) => {
const { userEmail, titlu, locație, salariu } = job;// obțineți utilizatorul din DB
const utilizator = asteapta userCollection.findOne({ e-mail: userEmail });// începe sesiunea de tranzacție
const sesiune = asteapta connection.startSession();// rulează toate interogările bazei de date într-un bloc try-catch
încerca {
const transactionSuccess = asteapta session.withTransaction(asincron () => {
const job nou = asteapta jobCollection.create(
[
{
titlu,
Locație,
salariu,
poster: user._id,
},
],
{ sesiune }
);consolă.log("Creat nou treaba cu succes!");
consolă.log (newJob[0]);// adaugă job la lista utilizatorilor de joburi postate
const newJobId = newJob[0]._id;
const addedToUser = asteapta userCollection.findByIdAndUpdate(
ID-ul de utilizator,
{ $addToSet: { locuri de munca: newJobId } },
{ sesiune }
);consolă.log("Slujbă adăugată cu succes la lista de locuri de muncă a utilizatorului");
consolă.log (addedToUser);
});
dacă (succes tranzacție) {
consolă.log("Tranzacție DB efectuată cu succes");
} altfel {
consolă.log(„Tranzacția a eșuat”);
}
} captură (e) {
consolă.eroare (e);
consolă.log(„Nu s-au finalizat operațiunile cu baza de date”);
} in cele din urma {
asteapta session.endSession();
consolă.log(„Sesiunea tranzacției încheiată”);
}
};
Acest lucru ar produce același rezultat ca implementarea anterioară. Sunteți liber să alegeți ce stil să utilizați atunci când implementați tranzacțiile cu baze de date în MongoDB.
Această implementare nu folosește commitTransaction() și abortTransaction() funcții. Acest lucru se datorează faptului că withTransaction() funcția comite automat tranzacțiile reușite și le anulează pe cele eșuate. Singura funcție pe care ar trebui să o apelați în toate cazurile este session.endSession() funcţie.
Implementarea tranzacțiilor cu baze de date ACID în MongoDB
Tranzacțiile cu baze de date sunt ușor de utilizat atunci când sunt făcute corect. Acum ar trebui să înțelegeți cum funcționează tranzacțiile cu baze de date în MongoDB și cum le puteți implementa în aplicațiile Node.js.
Pentru a explora în continuare ideea tranzacțiilor ACID și modul în care funcționează în MongoDB, luați în considerare construirea unui portofel fintech sau a unei aplicații de blogging.