问题
I am using IBM mq(p800-005-160516.2) and Spring JMS template to post messages to MQ.My application is having one database resource and one MQ resource in global transaction.Problem is that it fails if i configure CachingConnnectionFactory
public class Xa {
public ConnectionFactory connectionFactory() throws Exception {
AtomikosConnectionFactoryBean atomikosConnectionFactoryBean = new AtomikosConnectionFactoryBean();
atomikosConnectionFactoryBean.setUniqueResourceName("pavan");
Properties xaProperties = new Properties();
xaProperties.setProperty("connectionNameList", hostName);
xaProperties.setProperty("queueManager", queueManager);
xaProperties.setProperty("channel", channel);
xaProperties.setProperty("transportType", 1);
atomikosConnectionFactoryBean.setXaProperties(xaProperties);
atomikosConnectionFactoryBean.setXaConnectionFactoryClassName("com.ibm.mq.jms.MQXAConnectionFactory");
return atomikosConnectionFactoryBean;
}
public CachingConnectionFactory cachingConnectionFactory() throws Exception{
CachingConnectionFactory factory = new CachingConnectionFactory();
factory.setSessionCacheSize(5);
factory.setTargetConnectionFactory(connectionFactory());
factory.setReconnectOnException(true);
factory.afterPropertiesSet();
return factory;
}
public static void main(String[] args) throws Exception {
Xa b = new Xa();
JmsTemplate jmsQueueTemplate = new JmsTemplate(b.cachingConnectionFactory());
long sr = System.currentTimeMillis();
IntStream.range(0, 1000).parallel().forEach(aa->{
UserTransaction userTransaction = new UserTransactionImp();
try {
userTransaction.begin();
jmsQueueTemplate.send(queueName, new MessageCreator() {
@Override
public Message createMessage(javax.jms.Session session)throws JMSException {
TextMessage textMessage = session.createTextMessage();
textMessage.setText("pavan"+aa);
return textMessage;
}});
userTransaction.commit();
} catch (Exception e) {
try {
userTransaction.rollback();
} catch (Exception e1) {
throw new RuntimeException(e1);
}
throw new RuntimeException(e);
}
});
System.out.println("time taken "+(System.currentTimeMillis()-sr));
}
}
This fails with an exception
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:487)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:570)
at
... 23 common frames omitted
Caused by: com.atomikos.jms.AtomikosJMSException: error during enlist: Failed to suspend branch: XAResourceTransaction: 31302E3234362E38392E31362E746D30303032363030323933:31302E3234362E38392E31362E746D3337
at com.atomikos.jms.AtomikosJMSException.throwAtomikosJMSException(AtomikosJMSException.java:55)
at com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProducerSupport.java:101)
at com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(AtomikosJmsMessageProducerProxy.java:69)
at com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(AtomikosJmsMessageProducerProxy.java:147)
at org.springframework.jms.connection.CachedMessageProducer.send(CachedMessageProducer.java:181)
at sun.reflect.GeneratedMethodAccessor68.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.jms.connection.CachedMessageProducer$Jms2MessageProducerInvocationHandler.invoke(CachedMessageProducer.java:293)
at com.sun.proxy.$Proxy53.send(Unknown Source)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:626)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:597)
at org.springframework.jms.core.JmsTemplate$4.doInJms(JmsTemplate.java:574)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:484)
... 25 common frames omitted
Caused by: com.atomikos.datasource.xa.session.InvalidSessionHandleStateException: Failed to suspend branch: XAResourceTransaction: 31302E3234362E38392E31362E746D30303032363030323933:31302E3234362E38392E31362E746D3337
at com.atomikos.datasource.xa.session.BranchEnlistedStateHandler.transactionSuspended(BranchEnlistedStateHandler.java:117)
at com.atomikos.datasource.xa.session.TransactionContext.transactionSuspended(TransactionContext.java:112)
at com.atomikos.datasource.xa.session.SessionHandleState.notifyBeforeUse(SessionHandleState.java:184)
at com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProducerSupport.java:97)
... 37 common frames omitted
Caused by: javax.transaction.xa.XAException: The method 'xa_end' has failed with errorCode '-4'.
at com.ibm.mq.jmqi.JmqiXAResource.end(JmqiXAResource.java:559)
at com.atomikos.datasource.xa.XAResourceTransaction.xaSuspend(XAResourceTransaction.java:883)
at com.atomikos.datasource.xa.session.BranchEnlistedStateHandler.transactionSuspended(BranchEnlistedStateHandler.java:113)
... 40 common frames omitted
any help would be much appreciated
This works fine with transaction template
public static void main(String[] args) throws Exception {
TXTemplateExample b = new TXTemplateExample();
JmsTemplate jmsQueueTemplate = new JmsTemplate(b.cachingConnectionFactory());
jmsQueueTemplate.setSessionTransacted(true);
setAtomikosProperties();
long sr = System.currentTimeMillis();
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(60);
jtaTransactionManager.setUserTransaction(userTransactionImp);
UserTransactionManager userTransactionManager = new UserTransactionManager();
jtaTransactionManager.setTransactionManager(userTransactionManager );
TransactionTemplate txTmp = new TransactionTemplate(jtaTransactionManager);
LongStream.range(0, 10).parallel().forEach(index -> {
txTmp.execute(new TransactionCallbackWithoutResult() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
try {
jmsQueueTemplate.send(queueName, (session) -> {
TextMessage msg = session.createTextMessage();
msg.setText("pavan");
return msg;
});
} catch (Exception e) {
status.setRollbackOnly();
}
}
});
});
}
Whats wrong in creating usertransaction instead of using spring?
来源:https://stackoverflow.com/questions/46327445/jms-doesnt-work-in-global-transaction-with-cachingconnectionfactory