我正在为未来的项目评估 Mikro-Orm。有几个问题我要么在文档中找不到答案,要么没有完全理解它们。
让我描述一个最小复杂示例(NestJS):我有一个包含两个实体的订单处理系统:Orders
以及Invoices
一个用于顺序发票编号的计数器表(法律要求)。值得一提的是,OrderService 创建方法并不总是由控制器调用,也可以通过 crobjob/queue 系统调用。我的问题是关于创建新订单的用例:
class OrderService {
async createNewOrder(orderDto) {
const order = new Order();
order.customer = orderDto.customer;
order.items = orderDto.items;
const invoice = await this.InvoiceService.createInvoice(orderDto.items);
order.invoice = invoice;
await order.persistAndFlush();
return order
}
}
class InvoiceService {
async create(items): Invoice {
const invoice = new Invoice();
invoice.number = await this.InvoiceNumberService.getNextInSequence();
// the next two lines are external apis, if they throw, the whole transaction should roll back
const pdf = await this.PdfCreator.createPdf(invoice);
const upload = await s3Api.uplpad(pdf);
return invoice;
}
}
class InvoiceNumberService {
async getNextInSequence(): number {
return await db.collection("counter").findOneAndUpdate({ type: "INVOICE" }, { $inc: { value: 1 } });
}
}
使用所有后续服务调用创建新订单的整个用例应该发生在一个 Mikro-Orm 事务中。因此,如果在 OrderService.createNewOrder() 或随后调用的方法之一中抛出任何东西,则应该回滚整个事务。
Mikro-Orm 不允许 InvoiceNumberService 中显示的原子更新增量。我可以回退到本地 mongo 驱动程序。但是如何确保对 collection.findOneAndUpdate() 的调用与 Mikro-Orm 管理的实体共享相同的事务?
Mikro-Orm 需要一个独特的请求上下文。在 NestJS 的示例中,这个独特的上下文是在控制器级别创建的。在上面的示例中,服务方法不一定由控制器调用。因此,对于 OrderService.createNewOrder() 的每次调用,我都需要一个新的上下文,其生命周期范围为函数调用,对吗?我怎样才能做到这一点?
如何在服务之间共享相同的请求上下文?在上面的示例中,InvoiceService 和 InvoiceNumberService 需要与 OrderService 相同的上下文才能使 Mikro-Orm 正常工作。