У меня есть приложение, в котором мне нужно хранить некоторые данные в базе данных (например, mysql), а затем публиковать некоторые данные в очереди сообщений. Моя проблема: если приложение сработает после хранения в базе данных, мои данные никогда не будут записаны в очередь сообщений, а затем будут потеряны (таким образом, в конечном итоге моя система не будет гарантирована). Как я могу решить эту проблему?Возможная согласованность с записями базы данных и записей сообщений
ответ
У меня есть приложение, в котором мне нужно хранить некоторые данные в базе данных (например, mysql), а затем публиковать некоторые данные в очереди сообщений. Моя проблема: если приложение сработает после хранения в базе данных, мои данные никогда не будут записаны в очередь сообщений, а затем будут потеряны (таким образом, в конечном итоге моя система не будет гарантирована). Как я могу решить эту проблему ?
В этом конкретном случае ответом является загрузка данных очереди из базы данных.
То есть вы пишете сообщения, которые должны быть поставлены в очередь в базу , в той же транзакции, которую вы используете для записи данных. Затем, асинхронно, вы читаете эти данные из базы данных и записываете их в очередь.
См. Reliable Messaging without Distributed Transactions, Udi Dahan.
Если приложение аварийно завершает работу, восстановление происходит просто - во время перезагрузки вы запрашиваете базу данных для всех непризнанных сообщений и отправляете их снова.
Обратите внимание, что эта конструкция действительно ожидает, что потребители сообщений будут разработаны для at least once delivery.
Очень полезное видео. Но я удивлен, что нет известных библиотек, которые делают «часть» процесса – ayorosmage
. Более того, необходима база данных, поддерживающая транзакции. Таким образом, я думаю, что базы данных nosql, такие как mongodb, не могут быть использованы для этого. – ayorosmage
Должны ли быть события домена идемпотентны? Являются ли другие варианты для реализации возможной согласованности с использованием событий, отличных от idempotent? – xfg
Это слишком долго для комментария.
Я предполагаю, что у вас есть очередь сообщений без потерь, где, как только вы получите подтверждение для записи данных, в очереди гарантируется запись.
В принципе, вам нужен цикл с транзакцией, которая может откат или статус в базе данных. Псевдо-код для сделки:
- начать транзакцию
- Вставьте в базу данных
- Запись в очередь сообщений
- Когда очередь сообщений подтверждает, фиксации транзакции
Лично я бы, вероятно, сделать это со статусом:
- Вставьте в базу данных со статусом «в ожидании» (или что-то в этом роде)
- Запись в очередь сообщений
- Когда сообщение, подтверждающее, изменить статус на «приверженность» (или что-то подобное)
В случае восстановления после сбоя, вам может потребоваться проверить очередь сообщений, чтобы увидеть, действительно ли какие-либо «ожидающие» записи были записаны в очередь.
Спасибо за ваш ответ, я до сих пор есть некоторые проблемы: 1) Если я пишите в очередь сообщений перед совершением транзакции, сообщение в очереди может быть обработано до совершения транзакции. 2) Если мой идентификатор создается базой данных, я не могу включить его в сообщение, отправленное в очередь. – ayorosmage
В дополнение к тому, что сказал @Gordon Linoff, предполагая, что долговечный обмен сообщениями (что-то вроде MSMQ?), Метод/обработчик будет транзакционным, поэтому, если все будет успешным, сообщение будет записано в очередь и данные на ваш просмотреть модель, если она не удалась, все провалится ...
Чтобы уменьшить проблему с идентификатором, вам нужно будет использовать GUID вместо ключей сгенерированных БД (если вы используете обмен сообщениями, в любом случае вам нужно будет удалить вашу ссылочную целостность и ввести GUIDS как ключи).
Еще одно предложение: не обновляйте базу данных, а только вставку/upsert (ожидающую строку, а затем завершенную строку) и попросите читателя выполнить проекцию данных на основе последней строки (например)
Вы должны были бы трекер, который знает, какие сообщения были отправлены и то, что не были отправлены –
Это может помочь https://vimeo.com/111998645 – tomliversidge