We are using Bitronix XA as the jta transaction manager in our spring boot app. Problem is that it is making multiple connections that eats up resources on the MQ server. We are using IBM websphere as MQ server. For some reason Bitronix is not honouring the poolsize that we have given. Another observation is that connection leaks happen when we receive or send a burst of messages concurrently. Below are the configurations in code. Please advise how to solve the connection leak problem.
PoolingConnectionFactory:
PoolingConnectionFactory connectionFactory = new PoolingConnectionFactory();
connectionFactory.setClassName("com.ibm.mq.jms.MQXAQueueConnectionFactory");
connectionFactory.setUniqueName(XA_FACTORY_NAME);
connectionFactory.setAllowLocalTransactions(false);
connectionFactory.setTestConnections(true);
connectionFactory.setUser(user);
connectionFactory.setPassword(password);
connectionFactory.setMaxPoolSize(20);
Properties driverProperties = connectionFactory.getDriverProperties();
driverProperties.setProperty("port", ...);
driverProperties.setProperty("transportType", ...);
driverProperties.setProperty("channel", ...);
driverProperties.setProperty("hostName", ...);
driverProperties.setProperty("queueManager", ...);
Btm configs:
@Bean
@Profile({"cloud", "local"})
@DependsOn("instanceInfo")
public bitronix.tm.Configuration btmConfig() {
bitronix.tm.Configuration btmConfig = TransactionManagerServices.getConfiguration();
btmConfig.setDisableJmx(true);
btmConfig.setServerId(instanceInfo);
return btmConfig;
}
@Bean
@DependsOn("btmConfig")
public BitronixTransactionManager bitronixTransactionManager() {
BitronixTransactionManager transactionManager = TransactionManagerServices.getTransactionManager();
return transactionManager;
}
Messagecontainer used in SpringIntegrationFlows:
private DefaultMessageListenerContainer createMessageContainer(MessageListenerAdapter messageListenerAdapter,
ConnectionFactory connectionFactory, String queue, JtaTransactionManager jtaTransactionManager) {
DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
container.setMessageListener(messageListenerAdapter);
container.setConnectionFactory(connectionFactory);
container.setDestinationName(queue);
container.setSessionTransacted(true);
container.setTransactionManager(jtaTransactionManager);
container.setErrorHandler(containerErrorHandler);
return container;
}
PoolingDataSource for DB connection:
public PoolingDataSource createPooledDataSource(String driverClassName, String userName, String password, String jdbcURL, String validationQuery) {
PoolingDataSource dataSource = new PoolingDataSource();
dataSource.setUniqueName("dataSource");
dataSource.setMaxIdleTime(8);
dataSource.setMinPoolSize(1);
dataSource.setMaxPoolSize(20);
dataSource.setTestQuery(validationQuery);
dataSource.getDriverProperties().setProperty("user", userName);
dataSource.getDriverProperties().setProperty("password", password);
dataSource.getDriverProperties().setProperty("URL", jdbcURL);
dataSource.setClassName(driverClassName);
dataSource.setTestQuery(validationQuery);
dataSource.setAllowLocalTransactions(true);
dataSource.init();
return dataSource;
}