TypeORM 事务保存实体到数据库,尽管下一个事务步骤失败
TypeORM transaction saving entity to database despite the next transaction step failing
我想进行交易以保存新的 table 行和该行的多对多助手 table 条目。我正在使用相同的事务管理器保存两者,但是当第二部分失败时,第一部分不会恢复。为什么会这样?
await getManager().transaction(async transactionalEntityManager => {
newFeed = await transactionalEntityManager
.createQueryBuilder()
.insert()
.into(Feed)
.values({ ...feed })
.execute();
console.log('======================================\n', newFeed);
feed.sources.forEach(async source => {
console.log('==in forEach===\n', source.id, newFeed.identifiers[0].id);
await transactionalEntityManager
.createQueryBuilder()
.insert()
.into('feed_source')
.values({
sourceId: source.id,
feedId: newFeed.identifiers[0].id,
fontColor: feed.fontColor ? feed.fontColor : null,
postColor: feed.postColor ? feed.postColor : null
})
.execute();
});
});
是不是跟语法有关?我以前没有使用过插入查询构建器语法。 .execute() 是否以某种方式忽略了交易?这样做的正确方法是什么?
好的,所以我解决了。这是因为 forEach 的行为似乎是异步的,因此代码会在完成循环之前跳转到事务的末尾。在寻找解决方案时,我更改了我使用的方法和一些功能,因此代码最终变得完全不同,但主要是我使用 Promise.all() 并将 .map() 的结果传递给它返回承诺。
await getManager().transaction(async transactionalEntityManager => {
savedFeed = await transactionalEntityManager.save(newFeed);
if (feed.feedSources) {
newFeed.feedSources = [];
await Promise.all(
feed.feedSources.map(async feedSource => {
return new Promise(async (resolve, reject) => {
const referencedSource = await Source.findOne(feedSource.sourceId);
console.log('===referencedSource===\n', referencedSource);
if (!referencedSource)
throw new Error(
'Could not find referenced source with id ' + feedSource.id
);
const currentFeedSource = new FeedSource();
currentFeedSource.source = referencedSource;
currentFeedSource.feed = savedFeed;
feedSource.postColor
? (currentFeedSource.postColor = feedSource.postColor)
: '';
feedSource.fontColor
? (currentFeedSource.fontColor = feedSource.fontColor)
: '';
console.log('===currentFeedSource===\n', currentFeedSource);
await transactionalEntityManager.save(currentFeedSource);
resolve(true);
});
})
);
}
我想进行交易以保存新的 table 行和该行的多对多助手 table 条目。我正在使用相同的事务管理器保存两者,但是当第二部分失败时,第一部分不会恢复。为什么会这样?
await getManager().transaction(async transactionalEntityManager => {
newFeed = await transactionalEntityManager
.createQueryBuilder()
.insert()
.into(Feed)
.values({ ...feed })
.execute();
console.log('======================================\n', newFeed);
feed.sources.forEach(async source => {
console.log('==in forEach===\n', source.id, newFeed.identifiers[0].id);
await transactionalEntityManager
.createQueryBuilder()
.insert()
.into('feed_source')
.values({
sourceId: source.id,
feedId: newFeed.identifiers[0].id,
fontColor: feed.fontColor ? feed.fontColor : null,
postColor: feed.postColor ? feed.postColor : null
})
.execute();
});
});
是不是跟语法有关?我以前没有使用过插入查询构建器语法。 .execute() 是否以某种方式忽略了交易?这样做的正确方法是什么?
好的,所以我解决了。这是因为 forEach 的行为似乎是异步的,因此代码会在完成循环之前跳转到事务的末尾。在寻找解决方案时,我更改了我使用的方法和一些功能,因此代码最终变得完全不同,但主要是我使用 Promise.all() 并将 .map() 的结果传递给它返回承诺。
await getManager().transaction(async transactionalEntityManager => {
savedFeed = await transactionalEntityManager.save(newFeed);
if (feed.feedSources) {
newFeed.feedSources = [];
await Promise.all(
feed.feedSources.map(async feedSource => {
return new Promise(async (resolve, reject) => {
const referencedSource = await Source.findOne(feedSource.sourceId);
console.log('===referencedSource===\n', referencedSource);
if (!referencedSource)
throw new Error(
'Could not find referenced source with id ' + feedSource.id
);
const currentFeedSource = new FeedSource();
currentFeedSource.source = referencedSource;
currentFeedSource.feed = savedFeed;
feedSource.postColor
? (currentFeedSource.postColor = feedSource.postColor)
: '';
feedSource.fontColor
? (currentFeedSource.fontColor = feedSource.fontColor)
: '';
console.log('===currentFeedSource===\n', currentFeedSource);
await transactionalEntityManager.save(currentFeedSource);
resolve(true);
});
})
);
}