use sequelizejs to control mysql transactions. How to encapsulate or design transactions across methods and service?
The framework of
application is express + sequelizejs,. In the service layer, it often appears in one method to call other service methods, but it is required to be in the same transaction, so you can only get the transaction and pass it to other service after opening the transaction. Once the service changes, there are a lot of things that need to be changed
.
for example, when saving an article on one side, you need to store the relationship of the tags it contains in another table, and the operation of saving the relationship between the tag and the article is in two service, so you need to pass the transaction
.
//
async saveOrUpdateArticle(article: Article){
if(!article.tags && article.tags.length < 1){
throw new BusinessException("")
}
const result = await db.transaction().then(async (t) => {
try {
//
if(article.id){
article.updateAt = Date.now();
let originArticel = await this.getArticleById(article.id, t);
originArticel = await originArticel.update(article, {transaction: t});
//articleTag
}else{
//
const newArticle = await ArticleModel.create(article, {transaction: t});
//throw "abort the transaction";
const articleTags = [];
article.tags.forEach((tagId) => {
const articleTag: ArticleTag = {
articelId: newArticle.id,
tagId: tagId
};
articleTags.push(articleTag);
});
// articleTag
await this.services.articleTagService.saveOrUpdateArticleTags(articleTags, t);
}
await t.commit();
return true;
} catch (e) {
await t.rollback()
logger.error(e);
return false;
}
})
return result;
}
//
async saveOrUpdateArticleTags(articleTags: ArticleTag[], t){
const promiseList = [];
articleTags.forEach((articleTag) => {
promiseList.push(this.saveOrUpdateArticleTag(articleTag, t));
});
return await Promise.all(promiseList);
}
async saveOrUpdateArticleTag(articleTag: ArticleTag, t){
//
if(articleTag.id){
articleTag.updateAt = Date.now();
const originArticleTag = await this.getTagById(articleTag.id);
if(!originArticleTag){
throw new BusinessException(`id"${articleTag.id}"articleTag`);
}
articleTag = await originArticleTag.update(articleTag);
}else{
articleTag = await ArticleTagModel.create(articleTag, {transaction: t})
}
return articleTag;
}
when doing transaction operations, can you pass the transaction without parameters? do you have any good suggestions?