med mongoose i Node.js, kan någon berätta för mig hur denna kod ovan implementeras på nytt med den senaste transaktionsfunktionen
För att använda MongoDB multi-dokument transaktionsstöd i mongoose behöver du version större än v5.2. Till exempel:
npm install [email protected]
Mongoose transaktionsmetoder returnerar ett löfte snarare än en session som skulle kräva att await
används . Se:
- Transaktioner i Mongoose
- Blogg:A Node.JS Perspective on MongoDB 4.0:Transactions
Om du till exempel ändrar exemplet på resursen ovan och ditt exempel kan du prova:
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;
}
}
är inte atomär det finns alltid en möjlighet att användarplånbok uppdateras med belopp men relaterad transaktion skapas inte i transaktionsinsamlingen vilket resulterar i ekonomisk förlust
Du bör också överväga att ändra dina MongoDB-datamodeller. Speciellt om de två samlingarna är naturligt kopplade. Se även Modelldata för Atomic Operations för mer information.
Ett exempel på modell som du kan prova är Event Sourcing-modellen. Skapa en transaktionspost först som en händelse och beräkna sedan om användarens plånbokssaldo med hjälp av aggregering.
Till exempel:
{tranId: 1001, fromUser:800, toUser:99, amount:300, time: Date(..)}
{tranId: 1002, fromUser:77, toUser:99, amount:100, time: Date(..)}
Inför sedan en process för att beräkna mängden för varje användare per period som en cache beroende på krav (dvs. per 6 timmar). Du kan visa den aktuella användarens plånbokssaldo genom att lägga till:
- Det senaste cachelagrade beloppet för användaren
- Alla transaktioner för användaren har inträffat sedan det senaste cachade beloppet. dvs för 0-6 timmar sedan.