com mangusto em Node.js, alguém pode me dizer como esse código acima pode ser reimplementado usando o recurso de transações mais recente
Para usar o suporte a transações de vários documentos do MongoDB no mongoose, você precisa de uma versão superior a v5.2. Por exemplo:
npm install [email protected]
Os métodos transacionais do Mongoose retornam uma promessa em vez de uma sessão que exigiria o uso de
await
. Ver:- Transações no Mongoose
- Blog:uma perspectiva do Node.JS no MongoDB 4.0:transações
Por exemplo, alterando o exemplo no recurso acima e seu exemplo, você pode tentar:
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;
}
}
não é atômico há sempre a possibilidade de a carteira do usuário ser atualizada com o valor, mas a transação relacionada não é criada na cobrança de transações resultando em perda financeira
Você também deve considerar alterar seus modelos de dados do MongoDB. Especialmente se as duas coleções estiverem naturalmente ligadas. Consulte também Dados do modelo para operações atômicas para obter mais informações.
Um modelo de exemplo que você pode tentar é o modelo Event Sourcing. Crie uma entrada de transação primeiro como um evento e, em seguida, recalcule o saldo da carteira do usuário usando agregação.
Por exemplo:
{tranId: 1001, fromUser:800, toUser:99, amount:300, time: Date(..)}
{tranId: 1002, fromUser:77, toUser:99, amount:100, time: Date(..)}
Em seguida, introduza um processo para calcular a quantidade para cada usuário por período como um cache, dependendo dos requisitos (ou seja, por 6 horas). Você pode exibir o saldo da carteira do usuário atual adicionando:
- O último valor armazenado em cache para o usuário
- Todas as transações do usuário ocorrem desde o último valor armazenado em cache. ou seja, 0-6 horas atrás.