Node.js 7 et plus supporte déjà la syntaxe async/await. Comment dois-je utiliser async/await avec les transactions sequelize ?
Ça ne marche pas. t
dans ce cas, est une Promise et non l'objet de la transaction.
Node.js 7 et plus supporte déjà la syntaxe async/await. Comment dois-je utiliser async/await avec les transactions sequelize ?
let transaction;
try {
// get transaction
transaction = await sequelize.transaction();
// step 1
await Model.destroy({ where: {id}, transaction });
// step 2
await Model.create({}, { transaction });
// step 3
await Model.update({}, { where: { id }, transaction });
// commit
await transaction.commit();
} catch (err) {
// Rollback transaction only if the transaction object is defined
if (transaction) await transaction.rollback();
}
@Pier, await attend la sequelize.transaction() et en obtient ensuite le résultat. le t n'est pas la promesse, c'est le résultat de la promesse.
Je n'arrive pas à faire fonctionner l'attente lorsque je fais une commande .findOne(). Cela fonctionne-t-il avec ceci ?
La réponse acceptée est une "transaction non gérée", qui vous oblige à appeler commit
y rollback
explicitement. Pour quiconque souhaite une "transaction gérée", voici à quoi elle ressemblerait :
try {
// Result is whatever you returned inside the transaction
let result = await sequelize.transaction( async (t) => {
// step 1
await Model.destroy({where: {id: id}, transaction: t});
// step 2
return await Model.create({}, {transaction: t});
});
// In this case, an instance of Model
console.log(result);
} catch (err) {
// Rollback transaction if any errors were encountered
console.log(err);
}
Pour faire marche arrière, il suffit de lancer une erreur dans la fonction de transaction :
try {
// Result is whatever you returned inside the transaction
let result = await sequelize.transaction( async (t) => {
// step 1
await Model.destroy({where: {id:id}, transaction: t});
// Cause rollback
if( false ){
throw new Error('Rollback initiated');
}
// step 2
return await Model.create({}, {transaction: t});
});
// In this case, an instance of Model
console.log(result);
} catch (err) {
// Rollback transaction if any errors were encountered
console.log(err);
}
Si un code qui lance une erreur à l'intérieur du bloc de transaction, le rollback est automatiquement déclenché.
Merci beaucoup, cela fait un moment que je cherche cette solution. Je n'avais pas réalisé qu'on pouvait attendre sequelize.transaction
.
@hellowill89 - vous pouvez vérifier la documentation d'une fonction donnée. Si elle renvoie une Promise, alors vous pouvez utiliser await.
Property 'transaction' does not exist on type 'typeof import("/Users/mac/Projects/myinvoice-be/node_modules/sequelize/types/index")'. Did you mean 'Transaction'?ts(2551)
J'ai importé sequelize de import sequelize from 'sequelize';
La réponse donnée par l'utilisateur7403683 décrit la méthode async/await pour les transactions non gérées ( http://docs.sequelizejs.com/manual/tutorial/transactions.html#unmanaged-transaction-then-callback- )
Une transaction gérée dans le style async/await peut se présenter comme suit :
await sequelize.transaction( async t=>{
const user = User.create( { name: "Alex", pwd: "2dwe3dcd" }, { transaction: t} )
const group = Group.findOne( { name: "Admins", transaction: t} )
// etc.
})
En cas d'erreur, la transaction est automatiquement annulée.
Pour la couverture de test de la solution de l'utilisateur7403683 ci-dessus, envisagez d'utiliser sequelize-mock
y sinon
:
import SequelizeMock from 'sequelize-mock';
import sinon from 'sinon';
sandbox.stub(models, 'sequelize').returns(new SequelizeMock());
pour des transactions réussies :
sandbox.stub(model.sequelize, 'transaction')
.resolves({commit() {}});
and stub everything in the transaction block
commit() {} provides stubbing of transaction.commit(),
otherwise you'll get a "method does not exist" error in your tests
ou une transaction échouée :
sandbox.stub(models.sequelize, 'transaction').resolves({rollback() {}});
to cover transaction.rollback()
pour tester le catch()
logique.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.