问题
我试图用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)
])
}
}我想找出一个干净的方法来实现这一点,以前有没有人遇到过类似的问题?
谢谢大家!
发布于 2022-12-01 16:59:54
您的UserRepository.save和OrderRepository.save应该返回PrismaPromises而不是Promise(https://www.prisma.io/docs/concepts/components/prisma-client/transactions#the-transaction-api)
此外,当您await UserRepository.save返回的承诺时,您传递的是一个User,而不是$transaction所期望的PrismaPromise<User>。
要修复它,请按照上面的注释从存储库方法中修复输入,然后您应该能够通过倒转等待的顺序来完成事务:
await prisma.$transaction([
this.userService.create(userRequest),
this.orderService.create(orderRequest)
])发布于 2022-12-02 23:18:03
为此,您可以使用一个类型库,其中包括一个事务装饰器,它可以用于在单个事务中包装多个查询。或者,您可以在每个存储库中使用本机prisma事务客户端。这将涉及在需要使用事务客户端时将其传递给每个存储库。例如:
// repository layer
@injectable()
export class UserRepository{
constructor(@inject(PrismaClient) private prisma: PrismaClient)
save(user: IUser, transactionClient: Prisma.TransactionClient): Promise<User>{
return this.prisma.user.create({data: user}, {transaction: transactionClient});
}
}
@injectable()
export class OrderRepository{
constructor(@inject(PrismaClient) private prisma: PrismaClient)
save(order: IOrder, transactionClient: Prisma.TransactionClient): Promise<Order>{
return this.prisma.order.create({data: order}, {transaction: transactionClient});
}
}
// service layer
export class UserService{
constructor(@inject(UserRepository) private userRepo: UserRepository)
create(request: CreateUserRequest, transactionClient: Prisma.TransactionClient){
return this.userRepo.save(request, transactionClient);
}
}
export class OrderService{
constructor(@inject(OrderRepository) private orderRepo: OrderRepository)
create(request: CreateOrderRequest, transactionClient: Prisma.TransactionClient){
return this.orderRepo.save(request, transactionClient);
}
}
// controller layer
export UserController{
constructor(
@inject(UserService) private userService: UserService,
@inject(OrderService) private orderService: OrderService
){}
placeOrder(
userRequest: CreateUserRequest,
orderRequest: CreateOrderRequest
){
// create the transaction client
const transactionClient = this.prisma.transaction();
// perform transaction, if any fails go with rollback
this.prisma.$transaction([
await this.userService.create(userRequest, transactionClient),
await this.orderService.create(orderRequest, transactionClient)
])
}
}https://stackoverflow.com/questions/74516388
复制相似问题