-
Notifications
You must be signed in to change notification settings - Fork 38.5k
Enforced container-level acknowledge call for custom acknowledgement mode #34635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What kind of exception is being thrown from the In general, we do not recommend manual acknowledgement in a custom way in combination with Spring's message listener containers. Throwing an exception from the listener endpoint should do the right thing by default: recovering the JMS Session instead of acknowledging the Message. This is the only officially supported way to force redelivery of the current message. I suppose you use manual acknowledgement as an alternative to that default behavior? Are you using it to acknowledge the message early before starting the subsequent processing in your listener implementation, in which case we could simply ignore an exception from our default acknowledge call after the listener returned? Or are you expecting a non-manually-acknowledged message to be redelivered despite the listener endpoint having returned normally, specifically skipping the In terms of potential solutions, we could suppress certain exceptions when the acknowledge mode is non-standard, while still defensively trying our default acknowledge call which is necessary for proper default processing in common listener endpoints (which do not call acknowledge themselves and often do not even see the JMS Message, just a payload object). Alternatively, we could handle certain custom acknowledge modes on certain JMS provider specifically, in particular when the JMS Session needs to remain completely untouched - that is, with the Message not to be acknowledged at all and the Session not to be recovered either. However, that would be quite a semantic deviation in Spring's listener endpoint model. |
Hey Juergen,
|
Or if our processing was done, we ack the message in a reactor thread, but also in a listener thread. Our temporary solution was back to previous implementation of JmsAccessor#isClientAcknowledge, where we explicitly compare ack mode with client ack (this.ackMode == CLIENT_ACKNOWLEDGE) |
Interesting, so that's in combination with a Reactor pipeline in the listener endpoint. I did not expect that, thanks for clarifying. So you effectively accept some potential for losing a message by acknowleding it before it is fully processed? That's not the norm but fine if your system state can deal with it. Do I understand correctly that you are not trying to force redelivery through not acknowleding at all, rather just early acknowledging in your listener processing workflow? In that case, our |
Not really. We're never lose message because we do validation in our pipeline (in reactor thread), and ack message manual at the end (after even expection hadling). |
We can lose messages in case of |
So listener thread can ack message too early, and if appliaction goes down after that, but before reactor thread processing, we'll lose the message |
Ah ok, understood. That's the key difference to our regular processing scenario within the original listener thread: It does not hurt to do I'll reconsider what we can do to make your scenario work in a more obvious way. Simply suppressing For the time being, your workaround to tighten the |
Proposal that we've discussed with team is probably introduce feature flag to disable container-level ack (enable this by default) |
I've introduced an This is available in the latest 6.2.6 snapshot now. Please give it an early try! |
MR looks good. Tested with 6.2.6-SNAPSHOT. It works. Thanks for the quick feedback and fix! |
Good to hear! Thanks for the immediate feedback. |
Hello Spring comunity,
I was recently in the process of migrating a project from Spring Boot 2.6.14 to 3.3.4.
In our project we are using Tibco EMS, and their custom ack mode: EXPLICIT_CLIENT_ACKNOWLEDGE
(tibco doc), as we want to have control over each individual message.
After the migration I encountered the problem that during the acknowledgement exceptions were being thrown, while the messages were acknowledged.
The root of the problem was a new implementation of the isClientAcknowledgement method (added in this PR).
The problem flow is the following: read message -> manually acknowledge -> AbstractMessageListenerContainer tries to acknowledge the message a second time, which causes an exception to be thrown.
Link to the repo with the reproduced problem: link
In the above repo the problem was reproduced on Embedded ActiveMQ (with ack mode INDIVIDUAL_ACKNOWLEDGE), but it looks the same for Tibco EMS as well
The text was updated successfully, but these errors were encountered: