Transaction
Transaction нь хэд хэдэн үйлдлийг нэгэн зэрэг гүйцэтгэж, бүгд амжилттай болох эсвэл бүгд цуцлагдах баталгаа өгдөг. Банкны шилжүүлэг, захиалга баталгаажуулах зэрэг алдаа гарч болохгүй нөхцөлд зайлшгүй шаардлагатай.
ACID
Transaction-ийн 4 үндсэн шинж чанар:
| Шинж | Тайлбар | | --------------- | ----------------------------------------------------------------------- | | Atomicity | Бүгд хийгддэг эсвэл бүгд болихгүй — хагас дуусаагүй байдал байхгүй | | Consistency | Үйлдлийн өмнө болон дараа өгөгдөл зөв төлөвт байна | | Isolation | Нэг transaction нь нөгөө transaction-ийн дуусаагүй өөрчлөлтийг харахгүй | | Durability | Амжилттай болсон transaction-ийн өгөгдөл алдагдахгүй |
Replica set шаардлага
MongoDB transaction нь replica set (буюу Atlas) дээр л ажилладаг. Локал standalone MongoDB-д transaction дэмжигдэхгүй.
MongoDB Atlas-д replica set анхдагчаар идэвхтэй байдаг тул Atlas ашиглаж байгаа бол ямар ч тохиргоо хэрэггүй.
Session үүсгэх
Transaction нь session дотор явагддаг:
// Session үүсгэх
const session = client.startSession();
withTransaction() — transaction ажиллуулах
withTransaction() helper нь commit ба rollback-ийг автоматаар удирддаг — хамгийн хялбар арга:
const { MongoClient } = require("mongodb");
const client = new MongoClient(process.env.MONGODB_URI);
async function transferMoney(fromId, toId, amount) {
const session = client.startSession();
try {
await session.withTransaction(async () => {
const accounts = client.db("bank").collection("accounts");
// Мөнгө хасах
await accounts.updateOne(
{ _id: fromId, balance: { $gte: amount } },
{ $inc: { balance: -amount } },
{ session },
);
// Мөнгө нэмэх
await accounts.updateOne(
{ _id: toId },
{ $inc: { balance: amount } },
{ session },
);
});
console.log("Шилжүүлэг амжилттай боллоо");
} catch (error) {
console.error("Шилжүүлэг амжилтгүй болж, буцаагдлаа:", error);
} finally {
await session.endSession();
}
}
Дотор алдаа гарвал withTransaction() автоматаар rollback хийнэ — өөрөөр хэлбэл мөнгийг хасчихаад нэмэхдээ алдаа гарсан ч баланс хэвийн төлөвт буцна.
Гараар commit/abort хийх
withTransaction() ашиглахгүй бол commitTransaction ба abortTransaction-ийг гараар дуудна:
const session = client.startSession();
session.startTransaction();
try {
const orders = client.db("shop").collection("orders");
const products = client.db("shop").collection("products");
// Захиалга үүсгэх
await orders.insertOne(
{ userId: "u1", productId: "p1", amount: 50000 },
{ session },
);
// Нөөц багасгах
await products.updateOne({ _id: "p1" }, { $inc: { stock: -1 } }, { session });
// Бүгд амжилттай — commit
await session.commitTransaction();
console.log("Захиалга баталгаажлаа");
} catch (error) {
// Алдаа гарвал — rollback
await session.abortTransaction();
console.error("Захиалга цуцлагдлаа:", error);
} finally {
await session.endSession();
}
Transaction ашиглах хэзээ?
Transaction нь overhead нэмдэг тул бүх үйлдэлд хэрэглэх шаардлагагүй:
Transaction шаардлагатай:
- Мөнгөн шилжүүлэг (баланс хасах + нэмэх)
- Захиалга + нөөц нэгэн зэрэг өөрчлөх
- Олон collection-д атомик бичлэг хийх
Transaction хэрэггүй:
- Нэг document-д бичих — MongoDB нэг document-ийн бичлэг атомик
- Унших үйлдлүүд
- Бие даасан үйлдлүүд
// Transaction хэрэггүй — нэг document атомик
db.users.updateOne(
{ _id: userId },
{
$inc: { xp: 10 },
$addToSet: { completedLessons: "mongodb-19" },
$set: { lastActive: new Date() },
},
);
Дараагийн хичээлд:
MongoDB Atlas-ийн cloud үйлчилгээг хэрхэн ашиглах, холбогдох талаар үзнэ.