如何在使用其他服务的服务函数中使用nestjs中的事务?
async update(authContext: AuthContext, id: string, updatePortfolioDto: UpdatePortfolioDto, isSaved = false): Promise<Portfolio> {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try{
await this.sleeveService.deleteForPortfolio(authContext, id);
const updatedPortfolio = this.portfoliosRepository.update(id, portfolio);
await queryRunner.commitTransaction();
return updatedPortfolio
}catch(err){
await queryRunner.rollbackTransaction();
}finally{
await queryRunner.release();
}
}
更新是使用另一个服务sleeveService和portfolioRepository的服务方法
这是我当前的代码。但这不起作用,我该如何解决这个问题?
我有一个类似的问题,我解决了它(也许不是最好的方式)。但首先,有一个关于您的代码的重要说明。
根据 TypeOrm 文档
“请勿使用全局实体管理器。必须执行所有操作 使用提供的事务实体管理器。”
也就是说,您不应该在事务块内使用 portfoliosRepository 更新实体,而应使用 queryRunner.manager。
现在,如果您想与此事务中与您的实体一起使用的其他服务进行交互,您的任务是传递一个 EntityManager 实例(queryRunner.manager)。您调用的其他服务方法必须采用 EntityManager 作为参数。还需要使用此管理器在此方法中保存/更新/删除实体。
我给你举个例子。我的交易如下所示:
const queryRunner = this._dataSource.createQueryRunner()
await queryRunner.connect()
await queryRunner.startTransaction()
try {
this._logger.log(`Депозит баланса ${sum} на баланс задания ${task}`)
const taskBalance: TaskBalanceEntity = await queryRunner.manager.findOne(TaskBalanceEntity, {
where: {
taskId: task.id
}
})
userBalance.value = userBalance.value - sum
taskBalance.value = taskBalance.value + sum
await queryRunner.manager.save(UserBalanceEntity, userBalance)
await queryRunner.manager.save(TaskBalanceEntity, taskBalance)
await this._taskBalanceDepositHistotyService.create(queryRunner.manager, taskBalance, sum)
task.status = TaskStatus.ACTIVE
await queryRunner.manager.save(TaskEntity, task)
await queryRunner.commitTransaction()
return
} catch (error) {
this._logger.error(error)
await queryRunner.rollbackTransaction()
throw new InternalServerErrorException("Ошибка при завершении транзакции")
} finally {
await queryRunner.release()
}
在此示例中,您可以看到我正在调用另一个服务的方法this._taskBalanceDepositHistotyService.create(queryRunner.manager, taskBalance, sum),如下所示:
@Injectable()
export class TaskBalanceDepositHistoryService {
constructor(
@InjectRepository(TaskBalanceDepositHistoryEntity)
private readonly taskBalanceDepositHistoryRepository: Repository<TaskBalanceDepositHistoryEntity>
) {}
async create(entityManager: EntityManager, taskBalance: TaskBalanceEntity, value: number): Promise<void> {
const taskBalanceDepositHistory = this.taskBalanceDepositHistoryRepository.create()
taskBalanceDepositHistory.value = value
taskBalanceDepositHistory.taskBalanceId = taskBalance.id
await entityManager.save(TaskBalanceDepositHistoryEntity, taskBalanceDepositHistory)
}
}
我知道这个解决方案不是最好的,我很乐意查看其他解决方案。