如何应用nestjs已有的函数事务



我正在学习nestjs。

我有一个案例,我需要创建一个事务并执行多个函数。


async function1(updateDto:UpdateDto){
const queryRunner = getConnection().createQueryRunner();
await queryRunner.connect();
try{
await queryRunner.startTransaction();
//My function
await this.updateUser(updateDto);
await this.updateUserAndPet(updateDto);
await queryRunner.commitTransaction();
return true;
}catch (error) {
await queryRunner.rollbackTransaction();
return false;
} finally {
await queryRunner.release();
}
}

在上面的代码中,//My function下面的代码不是事务性的?

在每个函数中,执行await this.xxRepository.update()

如果交易不适用,我该怎么办?

我是否必须解压缩每个函数才能使用queryRunner?

如果还有别的办法,请告诉我。

谢谢!

在上面的代码中,下面的代码//我的函数不是事务性的?

否。因为在您的案例中,queryRunnerRepository.update之间没有连接。

为了";"连接";他们有两个选择:

  1. 使用myDataSource.manager.transaction创建的EntityManager
await dataSource.manager.transaction(async (transactionalEntityManager) => {
await transactionalEntityManager.save(user);
})
  1. 使用queryRunner.entityManager
await queryRunner.manager.save(user)

如果交易不适用,我该怎么办?

我认为在这种情况下,最直接的方法是将queryRunner.manager作为参数传递给函数(updateUserupdateUserAndPet(。并使用它对实体(而不是this.Repository.update(执行更新。因此,您仍然可以重用函数中的逻辑并保留分解
你不必"打开包装";它,但它附带了额外功能参数的成本。

对于事务,我通常使用一个特殊的类来实现";工作单位;图案:

工作单元跟踪您在可能影响数据库的业务事务中所做的一切。完成后,它会计算出由于您的工作而需要更改数据库的所有操作。

UnitOfWork.ts

import { Connection, EntityManager, QueryRunner } from "typeorm";
export interface WorkFunction<R> {
(entityManager: EntityManager): Promise<R>;
}
class UnitOfWork {
private readonly queryRunner: QueryRunner;
private readonly entityManager: EntityManager;
constructor(private connection: Connection) {
this.queryRunner = connection.createQueryRunner();
this.entityManager = this.queryRunner.manager;
}
public async start(): Promise<void> {
await this.queryRunner.connect();
await this.queryRunner.startTransaction();
}
public async commit<R>(work: WorkFunction<R>): Promise<R> {
try {
const result = await work(this.entityManager);
await this.queryRunner.commitTransaction();
return result;
} catch (err) {
await this.queryRunner.rollbackTransaction();
throw err;
} finally {
await this.queryRunner.release();
}
}
}
export default UnitOfWork;

UnitOfWork的使用

import { Connection, Repository } from "typeorm";
class UsersService {
constructor( private connection: Connection) {}
public async updateUserAndPet(user: UserEntity, pet: PetEntity): Promise<void> {
const work: WorkFunction<void> = async entityManager => {
await entityMagager.update(UserEntity, user.id, { pet_id: pet.id });
await entityMagager.update(PetEntity, user.id, { status: "happy" });
};
const uow = new UnitOfWork(this.connection);
await uow.start();
await uow.commit(work);
}
}

但是,如果不能将两个函数的逻辑提取到一个地方,则可能不适合您的情况。