Как удалить сообщения из темы - PullRequest
5 голосов
/ 27 ноября 2011

Я пытаюсь написать приложение, которое использует модель подписки публикации JMS. Однако, я столкнулся с неудачей, я хочу, чтобы издатель мог удалять сообщения из темы. Дело в том, что у меня есть постоянные подписчики, активные получат сообщения (так как это более или менее мгновенно), но если они неактивны и издатель решает, что сообщение неверно, я хочу, чтобы он мог удалить сообщение так что подписчики больше не получат его, как только станут активными. Проблема в том, что я не знаю, как / если это можно сделать. Для поставщика я остановился на реализации Glassfish, но если другие альтернативы предлагают эту функциональность, я могу переключиться.

Спасибо.

Ответы [ 3 ]

7 голосов
/ 27 ноября 2011

JMS - это форма асинхронного обмена сообщениями, поэтому издатели и подписчики отделены друг от друга.Это означает, что нет механизма, чтобы делать то, что вы просите.Для подписчиков, которые активны на момент публикации, они будут использовать сообщение, не имея возможности вовремя получить сообщение об удалении, чтобы действовать в соответствии с ним.Если подписчик находится в автономном режиме, то он будет, но асинхронные сообщения должны быть атомарными.Если вы приступите к разработке ответа другого респондента (создайте сообщение об удалении и потребует повторного подключения потребителей, чтобы прочитать всю очередь в поисках сообщений об удалении), то вы создадите ситуацию, в которой поведение системы будет различаться в зависимости от того, подписчик или нетбыл в сети или нет в то время, когда была опубликована конкретная комбинация сообщение / удаление.Существует также условие гонки, при котором подписчик завершает чтение сохраненных сообщений непосредственно перед тем, как издатель отправит сообщение об удалении.Это означает, что вы должны вкладывать существенную логику в подписчиков, чтобы согласовать эти условия и даже больше, чтобы согласовать состояние гонки.

Принятый метод выполнения этого называется так называемыми "компенсационными транзакциями".В любой системе, где производитель и потребитель не совместно используют одну единицу работы или разделяют общее состояние (например, используют одну и ту же БД для хранения состояния), тогда для возврата или исправления предыдущей транзакции требуется вторая транзакция, которая переворачивает первую.Конечно, потребитель должен быть в состоянии правильно применить компенсационную транзакцию.Когда используется этот шаблон, результатом является то, что все подписчики демонстрируют одинаковое поведение независимо от того, используются ли сообщения в режиме реального времени или в пакете после перезапуска потребителя.

Обратите внимание, что компенсирующая транзакция отличается от «удаления сообщения».Сообщение об удалении, предложенное в ответе другого респондента, является формой командования и управления, которая влияет на сам поток сообщений.С другой стороны, компенсирующие транзакции влияют на состояние системы через транзакционные обновления состояния системы.

Как правило, вы никогда не хотите управлять состоянием системы, манипулируяпоток сообщений с функциями управления и контроля.Это хрупкий, подверженный атакам и очень сложный для аудита или отладки.Вместо этого разработайте систему для доставки каждого сообщения с учетом ограничений по качеству обслуживания и обработки всех сообщений.Обрабатывать изменения состояния (включая отмену предыдущего действия) целиком в приложении.

Например, в банковском деле, где транзакции вызывают вторичные эффекты, такие как сборы за овердрафт, обычной процедурой является «запоминание» транзакций во времядень, затем отсортируйте и примените их в пакете после закрытия банка.Это позволяет примирить ошибку до , что приводит к выплате овердрафта.В последнее время транзакции применяются в режиме реального времени, но триггеры удерживаются до закрытия дневных книг, и это приводит к тому же результату.

1 голос
/ 27 ноября 2011

JMS API не позволяет удалять сообщения из любого места назначения (очереди или темы). Хотя я считаю, что определенные провайдеры JMX предоставляют свои собственные проприетарные инструменты для управления своим состоянием, например, с помощью JMX. Попробуйте проверить это для своего JMS-провайдера, но будьте осторожны: даже если вы найдете решение, оно не будет переносимым между различными JMS-провайдерами.

Один из законных способов «удалить» сообщение - использовать его время жизни: publish(Topic topic, Message message, int deliveryMode, int priority, long timeToLive). Вероятно, это достаточно хорошо для вас.

Если это не применимо для вашего приложения, решите проблему на уровне приложения. Например, прикрепите уникальный идентификатор к каждому сообщению и опубликуйте специальное «удалить» сообщение с более высоким приоритетом, которое будет своего рода командой для удаления «реального» сообщения с тем же идентификатором.

0 голосов
/ 27 ноября 2011

У вас есть производитель, который отправляет сообщение delete, и потребитель должен прочитать все сообщения перед началом их обработки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...