met mangoest in Node.js, kan iemand me vertellen hoe deze bovenstaande code opnieuw kan worden geïmplementeerd met behulp van de nieuwste transactiefunctie
Om MongoDB-ondersteuning voor transacties met meerdere documenten in mangoest te gebruiken, hebt u een versie hoger dan v5.2 nodig. Bijvoorbeeld:
npm install [email protected]
Transactiemethoden van Mongoose retourneren een belofte in plaats van een sessie waarvoor await
moet worden gebruikt . Zie:
- Transacties in mangoest
- Blog:een Node.JS-perspectief op MongoDB 4.0:transacties
Als u bijvoorbeeld het voorbeeld van de bron hierboven en uw voorbeeld wijzigt, kunt u proberen:
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 niet atomair, er is altijd een mogelijkheid dat de gebruikersportemonnee wordt bijgewerkt met het bedrag, maar de gerelateerde transactie is niet gemaakt in het verzamelen van transacties, wat resulteert in financieel verlies
Overweeg ook om uw MongoDB-gegevensmodellen te wijzigen. Zeker als de twee collecties van nature met elkaar verbonden zijn. Zie ook Modelgegevens voor Atomic Operations voor meer informatie.
Een voorbeeldmodel dat u zou kunnen proberen, is het Event Sourcing-model. Maak eerst een transactie-invoer als een gebeurtenis en bereken vervolgens het saldo van de portemonnee van de gebruiker opnieuw met behulp van aggregatie.
Bijvoorbeeld:
{tranId: 1001, fromUser:800, toUser:99, amount:300, time: Date(..)}
{tranId: 1002, fromUser:77, toUser:99, amount:100, time: Date(..)}
Voer vervolgens een proces in om het bedrag voor elke gebruiker per periode als cache te berekenen, afhankelijk van de vereisten (d.w.z. per 6 uur). U kunt het portemonnee-saldo van de huidige gebruiker weergeven door het volgende toe te voegen:
- Het laatste gecachte bedrag voor de gebruiker
- Alle transacties voor de gebruiker vinden plaats sinds het laatste bedrag in de cache. d.w.z. 0-6 uur geleden.