[英]Configuring AtomikosConnectionFactoryBean with spring integration message driven channel adapter
我正在嘗試使用 Atomikos 進行 Spring 集成項目的分布式事務管理。 如果我嘗試在消息驅動的通道適配器中使用 AtomikosConnectionFactoryBean 作為連接工廠,我會遇到問題。
我收到以下錯誤:
Caused by: com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ0018: Failed to connect to queue manager 'NYHUB6S' with connection mode 'Client' and host name 'nyhub6s.us.ml.com'.
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:608) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:236) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:430) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.wmq.internal.WMQXAConnection.<init>(WMQXAConnection.java:70) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.wmq.factories.WMQXAConnectionFactory.createV7ProviderConnection(WMQXAConnectionFactory.java:190) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:6210) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.wmq.factories.WMQXAConnectionFactory.createProviderXAConnection(WMQXAConnectionFactory.java:102) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createXAConnectionInternal(JmsConnectionFactoryImpl.java:371) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.mq.jms.MQXAQueueConnectionFactory.createXAQueueConnection(MQXAQueueConnectionFactory.java:144) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.mq.jms.MQXAQueueConnectionFactory.createXAConnection(MQXAQueueConnectionFactory.java:98) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.atomikos.datasource.xa.jms.JmsTransactionalResource.refreshXAConnection(JmsTransactionalResource.java:73) ~[transactions-jta-4.0.4.jar:na]
... 17 common frames omitted
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2009' ('MQRC_CONNECTION_BROKEN').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:223) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
... 26 common frames omitted
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2009;AMQ9204: Connection to host 'nyhub6s.us.ml.com(1467)' rejected. [1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2009],3=nyhub6s.us.ml.com(1467),5=RemoteRcvThread.run]
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:2072) ~[com.ibm.mq.jmqi-7.0.1.8.jar:7.0.1.8 - k701-108-120201]
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1286) ~[com.ibm.mq.jmqi-7.0.1.8.jar:7.0.1.8 - k701-108-120201]
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:345) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
... 25 common frames omitted
com.ibm.mq.jmqi.JmqiException: CC=2;RC=2009
at com.ibm.mq.jmqi.remote.internal.RemoteRcvThread.run(RemoteRcvThread.java:362) ~[com.ibm.mq.jmqi-7.0.1.8.jar:7.0.1.8 - k701-108-120201]
at com.ibm.msg.client.commonservices.workqueue.WorkQueueItem.runTask(WorkQueueItem.java:209) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.commonservices.workqueue.SimpleWorkQueueItem.runItem(SimpleWorkQueueItem.java:100) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.commonservices.workqueue.WorkQueueItem.run(WorkQueueItem.java:224) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.commonservices.workqueue.WorkQueueManager.runWorkQueueItem(WorkQueueManager.java:298) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
at com.ibm.msg.client.commonservices.j2se.workqueue.WorkQueueManagerImplementation$ThreadPoolWorker.run(WorkQueueManagerImplementation.java:1220) ~[com.ibm.mqjms-7.0.1.1.jar:7.0.1.1 - k701-101-091116]
我的 spring 集成和 Atomikos 配置如下:
<bean id="xaConnectionFactory" class="com.ibm.mq.jms.MQXAQueueConnectionFactory">
<property name="hostName">
<value>${receiving.queue.hostname}</value>
</property>
<property name="port">
<value>${receiving.queue.port}</value>
</property>
<property name="queueManager">
<value>${receiving.queue.manager}</value>
</property>
<property name="channel">
<value>${receiving.queue.channel}</value>
</property>
<property name="transportType">
<value>1</value>
</property>
</bean>
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="xaConnectionFactory" />
<property name="username" value="${mqSeriesUserName}" />
<property name="password" value="${mqSeriesPassword}" />
</bean>
<!-- lets wrap in a pool to avoid creating a connection per send -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="jmsQueueConnectionFactory"/>
<property name="sessionCacheSize" value="5"/>
<property name="reconnectOnException" value="true"/>
</bean>
<!--
<bean id="requestQueue1" class="com.ibm.mq.jms.MQQueue">
<property name="baseQueueName" value="${receiving.queue1}" />
JMSC.MQJMS_CLIENT_NONJMS_MQ is one
<property name="targetClient" value="1" />
</bean>
<bean id="requestQueue2" class="com.ibm.mq.jms.MQQueue">
<property name="baseQueueName" value="${receiving.queue2}" />
JMSC.MQJMS_CLIENT_NONJMS_MQ is one
<property name="targetClient" value="1" />
</bean>
<bean id="requestQueue3" class="com.ibm.mq.jms.MQQueue">
<property name="baseQueueName" value="${receiving.queue3}" />
JMSC.MQJMS_CLIENT_NONJMS_MQ is one
<property name="targetClient" value="1" />
</bean> -->
<!-- XA related changes -->
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
<property name="transactionTimeout" value="120"/>
<property name="forceShutdown">
<value>false</value>
</property>
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" >
</bean>
<bean id="atomikos_ConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean">
<property name="xaConnectionFactory" ref="xaConnectionFactory"/>
<property name="uniqueResourceName" value="MQSeries_XA_RMI"/>
<property name="poolSize" value="2" />
<property name="maxPoolSize" value="10" />
<property name="maxIdleTime" value="15" />
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager"> <ref bean ="atomikosTransactionManager"/></property>
<property name="userTransaction"> <ref bean="atomikosUserTransaction" /></property>
</bean>
<beans profile="SINGLE_REQUEST_Q">
<jms:message-driven-channel-adapter id="exch" destination="requestQueue" channel="jmsInChannel"
transaction-manager="transactionManager" acknowledge="transacted" connection-factory="atomikos_ConnectionFactory" />
<bean id="requestQueue" class="com.ibm.mq.jms.MQQueue">
<property name="baseQueueName" value="${receiving.queue.${exch}}" />
<property name="targetClient" value="1" />
</bean>
</beans>
我需要將帶有用戶 ID 和密碼的緩存工廠引用傳遞給AtomikosConnectionFactoryBean
但除了MQXAQueueConnectionFactory
之外,它不需要任何東西。 請讓我知道您將UserCredentialsConnectionFactoryAdapter
或CachingConnectionFactory
給AtomikosConnectionFactoryBean
bean 的意見或AtomikosConnectionFactoryBean
。
嘗試在UserCredentialsConnectionFactoryAdapter
和CachingConnectionFactory
為<jms:message-driven-channel-adapter>
使用atomikos_ConnectionFactory
。 像這樣的東西:
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="atomikos_ConnectionFactory" />
<property name="username" value="${mqSeriesUserName}" />
<property name="password" value="${mqSeriesPassword}" />
</bean>
...
<jms:message-driven-channel-adapter
transaction-manager="transactionManager" connection-factory="connectionFactory" />
一個解決方案是創建一個擴展 com.ibm.mq.jms.MQXAQueueConnectionFactory 的類並使用這個類代替 com.ibm.mq.jms.MQXAQueueConnectionFactory
當您擴展 MQXAConnectionFactory 時,定義屬性 username 和 password(以及 setter)並覆蓋方法 createXAConnection() 並創建這樣的上下文
public class MyMQXAConnectionFactory extends MQXAConnectionFactory {
private String username;
private String password;
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
/**
* create a connection with a context user/password if username is present
* @return
* @throws JMSException
*/
@Override
public XAConnection createXAConnection() throws JMSException {
if(username != null) {
createXAContext(this.username, this.password);
}
return super.createXAConnection(this.username, this.password);
}}
在您可以像這樣在 xml 配置文件中引用新類之后
<bean id="xaConnectionFactory" class="my.package.MyMQXAConnectionFactory">
<property name="hostName">
<value>${receiving.queue.hostname}</value>
</property>
<property name="port">
<value>${receiving.queue.port}</value>
</property>
<property name="queueManager">
<value>${receiving.queue.manager}</value>
</property>
<property name="channel">
<value>${receiving.queue.channel}</value>
</property>
<property name="transportType">
<value>1</value>
</property>
<property name="username" >
<value>${usernmame}/<value
</property>
<property name="password" >
<value>${password}</value>
</password>
</bean>
之后,您不需要 UserCredentialsConnectionFactoryAdapter 或 CachingConnectionFactory 並且您可以立即傳遞您的 XA bean
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.