【问题标题】:Nestjs with Typeorm Transaction in custom repositoryNestjs 与自定义存储库中的 Typeorm 事务
【发布时间】: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 的工作方式。

谢谢。

【问题讨论】:

    标签: typescript nestjs typeorm


    【解决方案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,我今天重试了,现在可以了:)
    猜你喜欢
    • 1970-01-01
    • 2021-01-07
    • 2021-06-07
    • 2019-02-01
    • 2020-04-19
    • 2019-05-09
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    相关资源
    最近更新 更多