使用实体存储库的全局实例在事务(TypeORM)中保存多个对象是否安全?

时间:2020-10-25 13:43:57

标签: typescript nestjs typeorm

来自TypeORM docs about transactions

在事务中工作时,最重要的限制是,在此示例中,始终使用提供的实体管理器实例-transactionalEntityManager。如果您要使用全局管理器(从getManager或从连接的管理器),则会遇到问题。您也不能使用使用全局管理器或连接来执行其查询的类。所有操作都必须使用提供的交易实体管理器执行。

那么使用这样的存储库是安全的:

    await this.myRepository.save(entities);

假设我希望在一次交易中保存所有实体?

我使用NestJS,而我的存储库来自全局模块注入范围:

@Injectable()
export class MyService {
  constructor(
    @InjectRepository(MyEntity) private readonly myRepository: Repository<MyEntity>,
  ) {}
  ...
}

表示每次都是相同的存储库实例。从SQL调试日志中,我可以看到一个事务已正确启动,并且给定实体的所有插入操作都在一个事务内,但是问题是是否存在一个极端的情况?

做什么:

如果您要使用全局管理器(从getManager或从连接的管理器),将会遇到问题。

确切指称吗?

1 个答案:

答案 0 :(得分:1)

好,那么交易在这里如何工作

await getManager().transaction(async transactionalEntityManager => {
    
});

您有一个专用的EntityManager实例,该实例将收集将在同一事务中运行的查询。您要询问的警告说您不能做类似的事情

await getManager().transaction(async transactionalEntityManager => {
    await transactionalEntityManager.save(users);
    await getRepository(Photo).save(photos); 
});

因为未在transactionalEntityManager上运行的部分将不会被注册为与第一个事务相同的事务的作用域。

在您的情况下,一切都很好,因为save()为信号保存操作创建了自己的事务。需要在单个事务中进行多次保存时,需要自己处理。在这种情况下,您必须使用此处https://docs.nestjs.com/techniques/database#transactions

所述的查询运行程序实例