Nestjs 与自定义存储库中的 Typeorm 事务

Posted

技术标签:

【中文标题】Nestjs 与自定义存储库中的 Typeorm 事务【英文标题】:Nestjs with Typeorm Transaction in custom repository 【发布时间】:2020-07-02 14:02:59 【问题描述】:

我有一个像这样使用 NestJS/Typeorm 的自定义存储库类:

import  Repository, EntityRepository, getConnection  from 'typeorm';
import  RefreshToken  from './refresh-token.entity';
import  User  from './user.entity';
import  InternalServerErrorException  from '@nestjs/common';

@EntityRepository(RefreshToken)
export class RefreshTokenRepository extends Repository<RefreshToken> 

  async refreshToken( token, user : RefreshToken): Promise<RefreshToken> 
    const connection = getConnection();
    const queryRunner = connection.createQueryRunner();

    // establish real database connection using our new query runner
    await queryRunner.connect();

    // lets now open a new transaction:
    await queryRunner.startTransaction();

    try 
      // execute some operations on this transaction:
      await queryRunner.manager.delete(RefreshToken,  token );

      const refreshToken = await queryRunner.manager.save(
        this.buildToken(user),
      );

      // commit transaction now:
      await queryRunner.commitTransaction();

      return refreshToken;
     catch (err) 
      // since we have errors lets rollback changes we made
      await queryRunner.rollbackTransaction();
     finally 
      // you need to release query runner which is manually created:
      await queryRunner.release();
    
  

请问有没有与我在refreshToken() 方法中所做的不同的方式来进行/建立交易?因为建立连接感觉很糟糕,而且不适合 NestJS 的工作方式。

谢谢。

【问题讨论】:

【参考方案1】:

您可以使用官方集成(包@nestjs/typeorm),以便您的代码不关心获取与数据库的连接(official documentation)。

使用TypeOrmModule (@nestjs/typeorm),您可以创建(和导入)负责建立与数据库的连接的动态模块。

@Module(
  imports: [
    TypeOrmModule.forRoot(
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    ),
  ],
)
export class AppModule 

那么您就不需要关心存储库代码中的连接了。

如果您已经使用“原始”TypeORM 创建了连接(比如说,当您的应用启动时),那么Repository 已经知道如何使用它。您可以直接处理您的请求,执行以下操作:

try 
  const refreshToken = await this.manager.transaction(async entityManager => 
    await entityManager.delete(RefreshToken,  token );
    return entityManager.save(RefreshToken, this.buildToken(user));
  );

  // commit done: use refreshToken here
 catch (error) 
  // rollback done: handle error here

您不能直接从存储库启动事务,但您可以访问(公共 API)其管理器,该管理器可以启动事务。它提供了一个*必须用于所有事务操作的实体管理器。

【讨论】:

非常感谢;我以前试过这些,经理回来了null,我今天重试了,现在可以了:)

以上是关于Nestjs 与自定义存储库中的 Typeorm 事务的主要内容,如果未能解决你的问题,请参考以下文章

如何将 NestJS 中的服务注入 typeorm 存储库?

Nest js 和 typeorm 自定义存储库问题

TypeError:存储库方法不是函数(NestJS / TypeORM)

在 Nestjs 中注入 Tree Typeorm 存储库

使用 TypeORM 和 Nestjs 进行测试的过程,以及使用 mocks 的玩笑?

什么是 nestjs typeorm 中的 getRepositoryToken 以及何时使用它?