Wrapped collection's creation in transaction

refs https://github.com/TryGhost/Arch/issues/16

- This is needed to avoid stale data/race conditions when processing collection post updates
This commit is contained in:
Naz 2023-07-19 22:11:28 +08:00 committed by naz
parent 0880770d50
commit 3dc27f505c
2 changed files with 31 additions and 22 deletions

View File

@ -22,7 +22,7 @@ const messages = {
};
interface SlugService {
generate(desired: string): Promise<string>;
generate(desired: string, options: {transaction: any}): Promise<string>;
}
type CollectionsServiceDeps = {
@ -190,30 +190,37 @@ export class CollectionsService {
}
async createCollection(data: CollectionInputDTO): Promise<CollectionDTO> {
const slug = await this.slugService.generate(data.slug || data.title);
const collection = await Collection.create({
title: data.title,
slug: slug,
description: data.description,
type: data.type,
filter: data.filter,
featureImage: data.feature_image,
deletable: data.deletable
});
if (collection.type === 'automatic' && collection.filter) {
const posts = await this.postsRepository.getAll({
filter: collection.filter
return await this.collectionsRepository.createTransaction(async (transaction) => {
const slug = await this.slugService.generate(data.slug || data.title, {
transaction: transaction
});
const collection = await Collection.create({
title: data.title,
slug: slug,
description: data.description,
type: data.type,
filter: data.filter,
featureImage: data.feature_image,
deletable: data.deletable
});
for (const post of posts) {
collection.addPost(post);
if (collection.type === 'automatic' && collection.filter) {
const posts = await this.postsRepository.getAll({
filter: collection.filter,
transaction: transaction
});
for (const post of posts) {
collection.addPost(post);
}
}
}
await this.collectionsRepository.save(collection);
await this.collectionsRepository.save(collection, {
transaction: transaction
});
return this.toDTO(collection);
return this.toDTO(collection);
});
}
async addPostToCollection(collectionId: string, post: CollectionPostListItemDTO): Promise<CollectionDTO | null> {

View File

@ -19,8 +19,10 @@ class CollectionsServiceWrapper {
postsRepository: postsRepository,
DomainEvents: DomainEvents,
slugService: {
async generate(input) {
return models.Collection.generateSlug(models.Collection, input, {});
async generate(input, options) {
return models.Collection.generateSlug(models.Collection, input, {
transacting: options.transaction
});
}
}
});