Whenever one of the transaction fails then also it did not aborts the transaction and transaction got partially committed. for example: when I send wrong registration number using postman then Publisher.findoneandUpdate an returns “TypeError: Cannot read property ‘$session’ of null” and the transaction should be aborted but it got partially committed like the code above Publisher line save it in the document.
i am using mongodb atlas
router.put('/', async (req, res) => {
try {
const today = new Date();
var month = (today.getMonth()) + 1;
var year = today.getFullYear();
var field = year + "-" + month;
var category = req.body.category;
var date = today.getDate();
const session = mongoose.startSession();
const transactionOptions = {
readPreference: 'primary',
readConcern: { level: 'local' },
writeConcern: { w: 'majority' }
};
const news = await News.findById(req.body.id);
var newsDate = new Date(news.createdAt).getDate();
var newsMonth = new Date(news.createdAt).getMonth() + 1;
var newsYear = new Date(news.createdAt).getFullYear();
// (await session).startTransaction();
// (await Publisher.findOneAndUpdate({ registrationNumber: req.body.registrationNumber }, { $inc: { [`monthlyViews.${field}`]: 1, [`categoriesViews.${category}`]: 1 } })).$session(session);
// if (newsDate == date && newsMonth == month && newsYear == year) {
// (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1, ['publishedDateViews']: 1 } })).$session(session);
// } else {
// (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1 } })).$session(session);
// }
// (await session).commitTransaction();
// res.status(200).send({ status: 1 });
const transactionResult = (await session).withTransaction(async () => {
var newsResult;
if (newsDate == date && newsMonth == month && newsYear == year) {
newsResult = (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1, ['publishedDateViews']: 1 } })).$session(session);
} else {
newsResult = (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1 } })).$session(session);
}
if (!newsResult) {
return (await session).abortTransaction();
}
const pubresult = (await Publisher.findOneAndUpdate({ registrationNumber: req.body.registrationNumber }, { $inc: { [`monthlyViews.${field}`]: 1, [`categoriesViews.${category}`]: 1 } })).$session(session);
if (!pubresult) {
return (await session).abortTransaction();
}
}, transactionOptions).then(result => { res.status(200).send({ status: 1 }); }).catch(e => {
console.log(e);
res.status(400).send({ status: 0 });
});
} catch (error) {
// (await session).abortTransaction();
console.error(error);
res.status(500).send({ status: 0, message: "Internal Server error" });
} finally {
(await session).endSession();
}
});
I also posted on Stack Overflow: