con mongoose in Node.js, qualcuno può dirmi come questo codice sopra può essere reimplementato utilizzando l'ultima funzione Transazioni
Per utilizzare il supporto per le transazioni multi-documento MongoDB in mongoose è necessaria una versione successiva alla v5.2. Ad esempio:
npm install [email protected]
I metodi transazionali Mongoose restituiscono una promessa piuttosto che una sessione che richiederebbe l'uso di await
. Vedi:
- Transazioni in Mongoose
- Blog:una prospettiva Node.JS su MongoDB 4.0:transazioni
Ad esempio, modificando l'esempio sulla risorsa sopra e il tuo esempio, puoi provare:
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;
}
}
non è atomico c'è sempre la possibilità che il portafoglio utente venga aggiornato con l'importo ma la transazione relativa non viene creata nella raccolta delle transazioni con conseguente perdita finanziaria
Dovresti anche considerare di cambiare i tuoi modelli di dati MongoDB. Soprattutto se le due collezioni sono naturalmente legate. Per ulteriori informazioni, vedere anche Dati modello per operazioni atomiche.
Un modello di esempio che potresti provare è il modello Event Sourcing. Crea prima una voce di transazione come evento, quindi ricalcola il saldo del portafoglio dell'utente utilizzando l'aggregazione.
Ad esempio:
{tranId: 1001, fromUser:800, toUser:99, amount:300, time: Date(..)}
{tranId: 1002, fromUser:77, toUser:99, amount:100, time: Date(..)}
Quindi introdurre un processo per calcolare l'importo per ciascun utente per periodo come cache a seconda dei requisiti (cioè per 6 ore). Puoi visualizzare il saldo del portafoglio dell'utente corrente aggiungendo:
- L'ultimo importo memorizzato nella cache per l'utente
- Qualsiasi transazione per l'utente si verifica dall'ultimo importo memorizzato nella cache. ovvero 0-6 ore fa.