This content has been marked as final.
Show 8 replies
-
1. Re: Can only send one message in XA transaction
timfox Nov 23, 2008 9:13 AM (in response to orankelly)Probably spring isn't enlisting the JBM xa resource properly with the global tx.
But I can't really comment on the internal workings of Spring. You're best best is to debug the Spring code, or ask a Spring expert. -
2. Re: Can only send one message in XA transaction
gaohoward Nov 23, 2008 10:37 PM (in response to orankelly)Can you also give the client code that consume the messages here? It may help to find the problem.
-
3. Re: Can only send one message in XA transaction
orankelly Nov 24, 2008 7:22 AM (in response to orankelly)"timfox" wrote:
Probably spring isn't enlisting the JBM xa resource properly with the global tx.
But I can't really comment on the internal workings of Spring. You're best best is to debug the Spring code, or ask a Spring expert.
Ok so, just to be sure, I have discarded the @Transactional annotations from the bean and modified the example above to manually get the UserTransaction, begin and commit that transaction around the sending of the messages and I get exactly the same behaviour - only one message is actually delivered, the first one that I "send". At this point, Spring isn't involved in the sending side of the transaction at all (well, ok, apart from wrapping a JDK proxy around my bean...see my note on deployment below).InitialContext ic = new InitialContext(); tx = (UserTransaction) ic.lookup("java:comp/UserTransaction"); tx.begin(); Context context = (Context) ic.lookup("java:comp/env"); Destination dest = (Destination) context.lookup("jms/MyTopic"); // jms/ConnectionFactory is tied to java:/JmsXA ConnectionFactory cf = (ConnectionFactory) context.lookup("jms/ConnectionFactory"); Connection conn = cf.createConnection(); Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = s.createProducer(dest); TextMessage m = s.createTextMessage("Message 1"); producer.send(m); m = s.createTextMessage("Message 2"); producer.send(m); m = s.createTextMessage("Message 3"); producer.send(m); s.close(); conn.close(); Thread.sleep(7000); tx.commit();
To clarify how I'm invoking the above code: I am still deploying the bean in a spring app context but I am exporting it as an MBean and then invoking an operation using jboss's jmx console. In this most recent effort, I turned on debug logging for spring's tx framework and have confirmed that it was not attempting to do anything transactional around my test (at debug level it is pretty verbose about what it's up to..) -
4. Re: Can only send one message in XA transaction
timfox Nov 24, 2008 7:30 AM (in response to orankelly)Are you doing this inside the app server?
You can only use the JMS JCA resource adapter (JmsXA) in a managed environment... -
5. Re: Can only send one message in XA transaction
orankelly Nov 24, 2008 7:30 AM (in response to orankelly)"gaohoward" wrote:
Can you also give the client code that consume the messages here? It may help to find the problem.
Sure, though it's very simple stuff:public class SimpleListener implements javax.jms.MessageListener { private static final Logger LOG = LoggerFactory.getLogger(SimpleListener.class); public void onMessage(Message message) { try { if (message instanceof TextMessage) { LOG.info("TextMessage received: {}", ((TextMessage) message).getText()); } else { LOG.info("{} received: {}", message.getClass().getSimpleName(), message); } } catch (Exception x) { LOG.error("", x); } } }
The output to my logs after invoking the sender code seen in earlier posts:2008-11-24 12:19:29,828 INFO [com.pbm.sms.event.SimpleListener] (WorkManager(2)-36) TextMessage received: Message 1
This is tied in to the topic using Spring's DefaultMessageListenerContainer (referencing the java:/JmsXA connection factory and JTA transaction manager). After posting this I will go away and write a plain MDB in order to further remove Spring from the equation but I'm not expecting much of a change in behaviour (famous last words...). -
6. Re: Can only send one message in XA transaction
timfox Nov 24, 2008 7:32 AM (in response to orankelly)"orankelly" wrote:
After posting this I will go away and write a plain MDB in order to further remove Spring from the equation
Yes please let's take Spring out of the equation. If you can demonstrate an issue using an MDB we can investigate further... -
7. Re: Can only send one message in XA transaction
orankelly Nov 24, 2008 7:32 AM (in response to orankelly)"timfox" wrote:
Are you doing this inside the app server?
You can only use the JMS JCA resource adapter (JmsXA) in a managed environment...
Yep, inside a running jboss-4.2.3.GA instance ("default" configuration, customised with jboss-messaging-1.4.0, 'jgroups.jar' copied over from the 'all' config as a jbm dependency but I'm not using a clustered config (yet)). -
8. Re: Can only send one message in XA transaction
orankelly Nov 24, 2008 10:05 AM (in response to orankelly)"timfox" wrote:
Yes please let's take Spring out of the equation. If you can demonstrate an issue using an MDB we can investigate further...
Famous last words indeed.
The root cause is some oddness with Spring's listener interacting with the tx manager. So the sending side was working but the listener was not getting all of the messages. As yet I have no idea why but if I stop populating the DefaultMessageListenerContainer's transactionManager property, all the messages are received.
When I deployed the simple MDB (identical code to that SimpleListener I posted earlier), all the messages were received correctly. I noticed some very odd behaviour with this new conf though, whereby my original listener, which I still had deployed, occasionally saw more than one message delivered - but never got all 3 and usually only got the first one.
Anyhoo - not a JBM issue!