TypeORM 是否为不同存储库提供事务?

mom*_*omo 11 typeorm nestjs

目前,三个不同的存储库需要将某些内容作为单个事务进行处理。

我的服务代码写如下。但与我想象的不同,每个存储库都生成自己的事务。我怎么解决这个问题?

// TrimService

@Injectable()
export class TrimService {
    constructor(
        private readonly trimRepository: TrimRepository,
        private readonly tireRepository: TireRepository,
        private readonly userRepository: UserRepository
    ) {}

    async saveUserTrim(saveUserTrimDto: SaveUserTrimDto, res) {
        const queryRunner = await getConnection().createQueryRunner();
        await queryRunner.startTransaction();

        try {
            const findUser: User = await this.userRepository.findUser(
                saveUserTrimDto.id,
                queryRunner.manager
            );

            const createTrim: Trim = await this.trimRepository.saveUserTrim(
                findUser,
                saveUserTrimDto.trimId,
                queryRunner.manager
            );

            await this.tireRepository.saveTrimTire(
                createTrim,
                res,
                queryRunner.manager
            );

            await queryRunner.commitTransaction();
            return createTrim;
        } catch (err) {
            console.log(err);
            await queryRunner.rollbackTransaction();
        } finally {
            await queryRunner.release();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
// userRepository

@EntityRepository(User)
export class UserRepository extends Repository<User> {
    async findUser(
        id: string,
        @TransactionManager() transactionManager?: EntityManager
    ) {
        const findUser = await this.findOne({ id: id });

        if (!findUser) {
            throw new NotFoundUserException();
        }

        return findUser;
    }
}
Run Code Online (Sandbox Code Playgroud)

mom*_*omo 10

我解决了这个问题。事务管理器从每个查询中接收并且必须使用该方法。由于userRepository是findOne,所以还没有进行事务处理。

// TrimService

@Injectable()
export class TrimService {
    constructor(
        private readonly trimRepository: TrimRepository,
        private readonly tireRepository: TireRepository,
        private readonly userRepository: UserRepository
    ) {}

    async saveUserTrim(saveUserTrimDto: SaveUserTrimDto, res) {
        const queryRunner = await getConnection().createQueryRunner();
        await queryRunner.startTransaction();

        const findUser: User = await this.userRepository.findUser(
            saveUserTrimDto.id
        );

        try {
            const createTrim: Trim = await this.trimRepository.saveUserTrim(
                queryRunner.manager,
                findUser,
                saveUserTrimDto.trimId
            );

            await this.tireRepository.saveTrimTire(
                queryRunner.manager,
                createTrim,
                res
            );

            await queryRunner.commitTransaction();
            return createTrim;
        } catch (err) {
            console.log(err);
            await queryRunner.rollbackTransaction();
        } finally {
            await queryRunner.release();
        }
    }
}

Run Code Online (Sandbox Code Playgroud)
// TrimRepository

@EntityRepository(Trim)
export class TrimRepository extends Repository<Trim> {
    async saveUserTrim(
        @TransactionManager() transactionManager: EntityManager,
        findUser: User,
        trimId: number
    ) {
        const findTrim = await transactionManager.findOne(Trim, {
            trimId: trimId,
            user: findUser
        });

        if (findTrim) {
            throw new TrimOverlapException();
        }

        const createTrim: Trim = await transactionManager.create(Trim, {
            trimId: trimId,
            user: findUser
        });

        return await transactionManager.save(Trim, createTrim);
    }
}

Run Code Online (Sandbox Code Playgroud)