Гнездо js с транзакцией Typeorm в пользовательском хранилище - PullRequest
0 голосов
/ 21 марта 2020

У меня есть собственный класс репозитория, подобный этому, с 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(), пожалуйста? Потому что установление соединения кажется нарушенным и не соответствующим тому, как работает Nest JS.

Спасибо.

1 Ответ

1 голос
/ 22 марта 2020

Вы можете использовать официальную интеграцию (пакет @nestjs/typeorm), чтобы ваш код не заботился о подключении к базе данных ( официальная документация ).

С TypeOrmModule (@nestjs/typeorm), вы можете создать (и импортировать) динамический c модуль, отвечающий за установление соединения с базой данных.

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

Тогда вам не нужно заботиться о соединении в коде ваших репозиториев.

Если вы уже создали соединение, используя «raw» 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
}

Вы не можете начать транзакцию напрямую из репозитория, но вы можете получить доступ (publi c API) к его менеджеру, который может запустить сделка. Он предоставляет менеджеру сущностей, который * должен использоваться для всех операций транзакции.

...