1 of 1 people found this helpful
you're probably not closing the sessions + not ACKing the message (seeing your other double post about ACKs).
Sorry about the double-post. I actually thought they were two different issues and didn't want to confuse things.
If the pre-ack is not effective, then wouldn't the default be auto-acknowledge, and isn't the ack / session management for MDBs handled by the application server anyway? I thought this was pretty much automatic.
BTW a quick profiler snapshot shows 1 session object, 0 producers, 1 consumer, but 69 connections (in desperation, I made sure I was closing *everything* after each publish). However, there are over 50,000 ServerMessageImpl objects. I am still tracking down why there are 69 connections (perhaps the RA is pooling them for me, despite my use of "java:/ConnectionFactory" instead of "java:/JmsXA" as a ref - which I thought I read was the only pooling factory). The high level of uncollected message objects is baffling if my producers, consumers, and sessions are all cleaned up.
1 of 1 people found this helpful
you're unlikely doing something wrong..
When you use java:/ConnectionFactory, acknowledge will depend on how you created the session. This connection factory goes outside of the context.
The ACK on MDBs will happen based on TX events (XA).
you should create a simple and self contained test to share if you think there's a bug , and someone would take a look.
Most likely you will find out what's wrong on the process of writing it.
I don't want to rule out the possibility of a bug, but a simple use case like this would likely been discovered already by now.
I wish there was a comparison table somewhere with the differences between the various connection factories. I'm sure this usage is our problem. I'm reluctant to use the JmsXA connection factory because we don't want to use XA transactions. We've hooked into the application server transaction manager to ensure that at commit, certain updates to caches occur *before* events are published via JMS whose recipient must see the updated values. It's not merely sufficient that the event *only* is sent when the transaction commits (which we also ensure), but that the event is sent *after* the cache updates are committed by our library.
So I'm sure I'm a strange case that is quite rarely seen (using the /ConnectionFactory binding inside the J2EE Server). If the connection factories behave as you say, and I'm not using XA transactions, perhaps I might try manually acknowledging each message from within our MDBs to see if that makes a difference.
(what we really need is a resource adapter implementation, within which we could perform all these operations in the sequence we desire at commit, have a local context for publishing in-vm instead of over the wire, and use transactions as they were envisioned, but unfortunately I'm a bit historically constrained). But even in such a case I would want to control the timing of the event publication, which would require that I do not use transactional messaging and send "immediately" from within our commit() logic.
This is I suppose my dilemma. How to use non-transactional messaging (so messages are published immediately and unconditionally), but receive via MDBs. And preferably using in-vm semantics (which we are currently not).
I added a manual message.acknowledge() call to my MDB base class, and all HornetQ message objects are now reclaimed. I'm a bit baffled by this, since I create all sessions with non-transactional (false), AUTO_ACKNOWLEDGE flags. If pre-acknowledge was working, that should have reclaimed objects. If not, my AUTO_ACKNOWLEDGE setting on the session should have. Baffled. But at least the problem is solved (albeit with a slightly undesirable manual ack).
Anyway, thanks for the assistance.