为了简化我的问题,我有
带有@Transactionnal 方法createUser() 的App1:
- 在数据库中插入新用户
- 在 RabbitMQ 中添加异步消息,以便用户收到通知邮件
- (可能有一些额外的代码,但不多)
带有 RabbitMQ 消息消费者的 App2
- 实时使用邮件队列中的消息
- 读取数据库中的邮件数据
- 发邮件
问题是,有时,App2 甚至在 App1 上提交事务之前尝试使用 RabbitMQ 消息。这意味着 App2 无法读取数据库上的邮件数据,因为尚未创建用户。
一些解决方案可能是:
- 在 App2 上使用 READ_UNCOMMITED 隔离级别
- 在 RabbitMQ 消息传递中添加一些延迟(或在消费者上添加一些 RetryTemplate)
- 改变我们发送电子邮件的方式...
我已经看到 Spring 中有一个 RabbitTransactionManager,但我不明白它应该如何工作。事务处理的内部结构似乎总是有点难以理解,文档也没有太大帮助。
有没有办法做这样的事情?
- 在 @Transactionnal 方法中向 RabbitMQ 队列添加消息
- 事务结束时,将消息提交到队列,并将更改提交到数据库
- 使消息在DB事务结束前不能被消费
如何?例如,如果我发送同步 RabbitMQ 消息而不是异步消息,会发生什么?它会阻塞等待响应的线程吗?因为我们确实为不同的用例发送同步和异步消息。