在消费者内部使用事务总线

Using transactional bus inside consumer

我有 REST API 网关,它使用 MassTransit 请求客户端调用微服务之一。此请求不持久,只能存在很短的时间 - 本质上它只是替换“传统”同步(通过 HTTP/GRPC/etc)网关微服务通信。

在微服务方面,我有消费者在后台使用 DbContext 和事务 (EFC) 在数据库中执行一些工作。工作完成后,它应该发布“WorkDoneEvent”(稍后由其他微服务使用)和 return 工作结果到 api 网关。事件必须与用于执行工作的事务一起以原子方式发布。 ApiGateway 是否会收到响应/是否会重试请求并不重要 - 一旦提交事务,工作结果和发送“WorkDoneEvent”都必须得到保证。

通常这是使用事务性发件箱完成的,事务性发件箱首先将发布的事件保存到工作完成时同一事务中的数据库。 (然后一些进程不断地“轮询”发件箱并尝试向代理发送消息,完成后它会从发件箱中删除消息)。据我所知。

MassTransit 似乎内置了交易发件箱:https://masstransit-project.com/advanced/middleware/transactions.html#transactional-bus

但是在文档中明确指出:

Never use the TransactionalBus or TransactionalEnlistmentBus when writing consumers. These tools are very specific and should be used only in the scenarios described.

而这正是我想要做的...

为什么我不应该这样做?

我建议使用 InMemoryOutbox,它是 MassTransit 的一部分。它的重量明显更轻,专为在消费者中工作而设计,并且在消费者完成之前(但在代理确认消息之前)不会发布您的事件。唯一需要考虑的是您的消费者应该是幂等的(在您的方法中也需要如此)并且如果操作已经在重试时执行,它应该重新发布事件。

videos, articles, and a sample个可以配合。