Mongo DB 4.0 Transactions With Mongoose & NodeJs, Express Mongo DB 4.0 Transactions With Mongoose & NodeJs, Express mongodb mongodb

Mongo DB 4.0 Transactions With Mongoose & NodeJs, Express


with mongoose in Node.js, can anyone tell me how this above code be reimplemented using the latest Transactions feature

To use MongoDB multi-documents transactions support in mongoose you need version greater than v5.2. For example:

npm install mongoose@5.2

Mongoose transactional methods returns a promise rather than a session which would require to use await. See:

For example, altering the example on the resource above and your example, you can try:

const User = mongoose.model('Users', new mongoose.Schema({  userId: String, wallet: Number}));const Transaction = mongoose.model('Transactions', new mongoose.Schema({  userId: ObjectId, amount: Number, type: String}));await updateWallet(userId, 500);async function updateWallet(userId, amount) {  const session = await User.startSession();  session.startTransaction();  try {    const opts = { session };    const A = await User.findOneAndUpdate(                    { _id: userId }, { $inc: { wallet: amount } }, opts);    const B = await Transaction(                    { usersId: userId, amount: amount, type: "credit" })                    .save(opts);    await session.commitTransaction();    session.endSession();    return true;  } catch (error) {    // If an error occurred, abort the whole transaction and    // undo any changes that might have happened    await session.abortTransaction();    session.endSession();    throw error;   }}

is not atomic there is always a possibility of user wallet updated with amount but related transaction not created in transactions collection resulting in financial loss

You should also consider changing your MongoDB data models. Especially if the two collections are naturally linked. See also Model data for Atomic Operations for more information.

An example model that you could try is Event Sourcing model. Create a transaction entry first as an event, then recalculate the user's wallet balance using aggregation.

For example:

{tranId: 1001, fromUser:800, toUser:99, amount:300, time: Date(..)}{tranId: 1002, fromUser:77, toUser:99, amount:100, time: Date(..)}

Then introduce a process to calculate the amount for each users per period as a cache depending on requirements (i.e. per 6 hours). You can display the current user's wallet balance by adding:

  • The last cached amount for the user
  • Any transactions for the user occur since the last cached amount. i.e. 0-6 hours ago.