網站搜尋

node.js - Prisma 交易跨模組


問題

我正在嘗試用 DDD 架構實現一個乾淨的 Prisma 交易架構。我的問題是,我希望能夠跨不同模組執行 transactions,而不需要將 prisma 交易客戶端傳遞給每個倉儲,例如:

// repository layer
@injectable()
export class UserRepository{
  constructor(@inject(PrismaClient) private prisma: PrismaClient)

  save(user: IUser): Promise<User>{
     return this.prisma.user.create({data: user});
  }
}

@injectable()
export class OrderRepository{
  constructor(@inject(PrismaClient) private prisma: PrismaClient)
  
  save(order: IOrder): Promise<Order>{
    return this.prisma.order.create({data: order});
  }
}
// service layer
export class UserService{
  constructor(@inject(UserRepository) private userRepo: UserRepository)

  create(request: CreateUserRequest){
    return this.userRepo.save(request);
  }
}

export class OrderService{
  constructor(@inject(OrderRepository) private orderRepo: OrderRepository)
  
  create(request: CreateOrderRequest){
    return this.orderRepo.save(request);
  }
}
// controller layer
export UserController{
   constructor(
    @inject(UserService) private userService: UserService,
    @inject(OrderService) private orderService: OrderService
   ){}

  placeOrder(
    userRequest: CreateUserRequest,
    orderRequest: CreateOrderRequest
  ){
    // perform transaction, if any fails go with rollback
    // !THIS ACTUALLY DOESN'T WORK
    prisma.$transaction([
       await this.userService.create(userRequest),
       await this.orderService.create(orderRequest)
    ])
  }
}

我想找出一個乾淨的方法來實現這個,有人以前遇過類似的問題嗎?

謝謝大家!

答案#1

您的 UserRepository.save 和 OrderRepository.save 應該返回 PrismaPromise 而不是 Promise(https://www.prisma.io/docs/concepts/components/prisma-client/transactions#the-transaction-api)

另外,當你 await 由 UserRepository.save 返回的 promise 時,你傳遞的是一個 User,而不是 PrismaPromise<User>,而這正是 $transaction 所期望的。

要修復它,按照上面評論的方式修正倉庫方法的類型,然後你應該能夠通過顛倒你等待的順序來進行交易:

await prisma.$transaction([
   this.userService.create(userRequest),
   this.orderService.create(orderRequest)
])