Чтобы упростить мою проблему, у меня есть
App1 с помощью метода @Transactionnal createUser():
- Вставить нового пользователя в базу данных
- Добавить асинхронное сообщение в RabbitMQ, чтобы пользователь получал почту с уведомлением
- (возможно, дополнительный код, но не много)
App2 с сообщением о контенте RabbitMQ
- Сообщает сообщения в очереди рассылки в режиме реального времени
- Чтение почтовых данных в базе данных
- Отправить почту
Проблема заключается в том, что иногда App2 пытается использовать сообщение RabbitMQ до того, как транзакция даже совершена в App1. Это означает, что App2 не может читать почтовые данные в базе данных, потому что пользователь еще не создан.
Некоторые решения могут быть:
- Используйте уровень изоляции READ_UNCOMMITED в App2
- Добавьте некоторую задержку в доставке сообщений RabbitMQ (или какой-либо RetryTemplate на consummer)
- Измените способ отправки писем...
Я видел, что в Spring есть RabbitTransactionManager, но я не могу понять, как он должен работать. Внутренние элементы обработки транзакций всегда кажутся немного трудными для понимания, и документация также не помогает.
Есть ли способ сделать что-то вроде этого?
- Добавить сообщение в очередь RabbitMQ в методе @Transactionnal
- Когда транзакция завершается, сообщение отправляется в очередь, а изменения заносятся в базу данных
- Чтобы сообщение не могло быть использовано до завершения транзакции db
Как? И что ожидать, например, если я отправляю синхронные сообщения RabbitMQ вместо асинхронных сообщений? Будет ли он блокировать поток, ожидающий ответа или что-то еще? Потому что мы отправляем сообщения синхронизации и асинхронного сообщения для разных случаев использования.