我试图在Spring Boot项目中使用Atomikos事务管理器来管理一些仅包含JMS但不包含数据源的事务操作。因此,我仅配置事务性JMS连接工厂,而不配置事务性数据源连接。出现以下错误:
Caused by: java.lang.NoClassDefFoundError: com/atomikos/jms/AtomikosConnectionFactoryBean
at com.tfkb.common.config.JMSConfig.xaQueueConnectionFactory(JMSConfig.java:275) ~[classes/:na]
at ...
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_121]
... 67 common frames omitted
我已经检查了pom.xml,目前,在这种情况下,我具有以下依赖性:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jms</artifactId>
<version>4.0.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jta</artifactId>
<version>4.0.4</version>
</dependency>
我已经搜索过,但是找不到Atomikos上下文中的任何特定内容。我还检查了bean的定义和用法,但一切看起来都很好。
我有以下配置:
import com.atomikos.jms.AtomikosConnectionFactoryBean;
import org.apache.activemq.ActiveMQXAConnectionFactory;
@Configuration
@EnableJms
@EnableTransactionManagement
@EnableAutoConfiguration
@PropertySource(ignoreResourceNotFound = true, value = "classpath:common.properties")
public class JMSConfig implements JmsListenerConfigurer {
...
@Bean(initMethod = "init", destroyMethod = "close", name = "xaQueueConnectionFactory")
public ConnectionFactory xaQueueConnectionFactory() {
ActiveMQXAConnectionFactory activeMQXAConnectionFactory = new ActiveMQXAConnectionFactory();
activeMQXAConnectionFactory.setBrokerURL(brokerURL);
activeMQXAConnectionFactory.setUserName(userName);
activeMQXAConnectionFactory.setPassword(password);
AtomikosConnectionFactoryBean atomikosConnectionFactoryBean = new AtomikosConnectionFactoryBean();
atomikosConnectionFactoryBean.setUniqueResourceName("xamq");
atomikosConnectionFactoryBean.setLocalTransactionMode(false);
atomikosConnectionFactoryBean.setXaConnectionFactory(activeMQXAConnectionFactory);
return atomikosConnectionFactoryBean;
}
package com.xxx.common.config;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import com.atomikos.jms.AtomikosConnectionFactoryBean;
import net.sf.ehcache.transaction.manager.TransactionManagerLookup;
import org.apache.activemq.ActiveMQXAConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import javax.inject.Inject;
import javax.jms.ConnectionFactory;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import java.util.Properties;
@Configuration
public class AtomikosJtaConfiguration {
@Inject
private Environment environment ;
public void tailorProperties(Properties properties) {
properties.setProperty( "hibernate.transaction.manager_lookup_class",
TransactionManagerLookup.class.getName());
}
@Bean
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(1000);
return userTransactionImp;
}
@Bean(initMethod = "init", destroyMethod = "close")
public TransactionManager transactionManager() throws Throwable {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(false);
return userTransactionManager;
}
还有
package com.xxx.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import org.springframework.transaction.jta.JtaTransactionManager;
import javax.inject.Inject;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
@Configuration
@EnableTransactionManagement
public class TxConfig {
@Inject
private AtomikosJtaConfiguration jtaConfiguration ;
@Bean
@Primary
public PlatformTransactionManager platformTransactionManager() throws Throwable {
UserTransaction userTransaction = jtaConfiguration.userTransaction() ;
TransactionManager transactionManager = jtaConfiguration.transactionManager() ;
return new JtaTransactionManager( userTransaction, transactionManager );
}
}
这是一个多模块项目,我将这些配置放在一个通用包中,调用者使用它们的方式如下:
@EntityScan(basePackages = "com.servicium.entity")
@ComponentScan({"com.xxx.alarmservice.impl", "com.xxx.common",
"com.xxx.common.interf", "com.xxx.common.config", "com.xxx.common.test"})
@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
@Import({MyConfig.class, RestTemplateConfig.class, SecurityConfig.class,
RequestLoggingConfig.class, JMSConfig.class, AtomikosJtaConfiguration.class, TxConfig.class})
public class AlarmServiceApplication {
...
}
在这个模块中,我有一个事务方法作为测试方法:
@Test
@Transactional
public void testReceiveXXX() throws Exception {
...
}
...
有人可以帮助我在Spring Boot项目中用JMS配置Atomikos吗?