Может ли сообщение стать отравленным, если оно не является транзакционным?
Документация, кажется, подразумевает, что нет, но я не нахожу прямого утверждения так или иначе.
Да, при некоторых обстоятельствах это возможно.
Ядовитое сообщение - это сообщение, которое остается в верхней части очереди, не позволяя другим пройти. Итак, что же делает транзакционные сообщения отравленными? Это когда мы откатываем транзакцию, и сообщение возвращается туда, где было раньше, прямо в начало очереди. Так что дело не в самом сообщении (по крайней мере, не напрямую), а в следствии того, как мы обрабатываем сообщения и что мы делаем в случае сбоя этой обработки, то есть выполняем откат.
Если очередь не транзакционная, и мы «получаем» сообщение сверху очереди, это необратимо. Нет никакого отката, который вернул бы сообщение на эту верхнюю позицию. Если мы хотим вернуть это сообщение в очередь, чтобы повторить попытку позже, все, что мы можем сделать, это отправить копию исходного сообщения. А MSMQ Send помещает его в конец очереди. Таким образом, он не может блокировать другие сообщения.
Есть один случай, когда это не применимо, и это если мы поиграем с приоритетом сообщения и отправим его обратно с более высоким приоритетом, чем остальная часть очереди. Это вернет его наверх и создаст сценарий опасного сообщения.
Другой способ состоит в том, что наша обработка состоит из «Peek» (который не удаляет сообщение), за которым следует «Receive», если обработка в порядке. Если обработка между Peek и Receive не удалась, сообщение останется в верхней части очереди.
Итак, да, подозрительные сообщения с нетранзакционными сообщениями могут быть, но только если делать что-то определенным образом.
Это нормально. Существует вероятность потери сообщения, если ваш процесс завершится ошибкой после получения, но до завершения обработки. Я бы хотел, чтобы вы включили ведение журнала для этой очереди, и все полученные сообщения попадут в журнал, так что, по крайней мере, вы ничего не потеряете.
Хотя это не заблокирует другие входящие сообщения, повторные сообщения могут появляться снова и снова. Вы можете добавить в сообщение «счетчик повторных попыток», если хотите остановить повторные попытки после, скажем, 10 повторных попыток и уведомить кого-нибудь о проверке. Будет проще, если вы поместите этот счетчик в поле «Расширение сообщения» или «Для конкретного приложения», но вы также можете изменить текст сообщения.
There is a possibility of message loss if your process fails after Receive and before processing is completed.
Ага! Попался там тоже :-) После успешной очереди Send()
сериализованный текстовый файл JSON.NET
помещается в папку журнала в файловой системе, чтобы быть удаленным только после успешного WCF Send()
. Я мог бы в конечном итоге сделать что-то с вставкой SQL в качестве дополнительной резервной копии. Эта функция ведения журнала выглядит интересной, но кажется сложным решить, как часто опорожнять это ведро. Здесь осторожность - лучшая часть доблести.
You can put some "retry counter" in a message if you want to stop retries after let's say 10 retries and notify someone to check it.
Хорошая идея, я сделаю это. It's easier if you put that counter in message's Extension, or "App specific" fields...
Хороший совет, проверю.
If processing fails between Peek and Receive, message would stay on the top of the queue.
Хм, это именно то, что я делаю. Я мог бы вместо этогоReceive()
, а затем вернуть его (с тем же приоритетом), если обработка не удалась - в данном случае отправка в службу WCF. Что ты предлагаешь?