我在Spring Boot应用程序中使用两个XA数据源时遇到问题。首先,我无法使用基本数据源,因为Spring JPA错误日志中的Hibernate实现要求我使用XA数据源,所以我切换到了这种类型的oracle.jdbc.xa.client.OracleXADataSource
的XA。服务器是WebLogic 12.2和数据库Oracle 12.我收到此错误(我从堆栈跟踪中解释所有原因,详细信息被忽略):
org.springframework.orm.jpa.JpaSystemException: Unable to acquire JDBC Connection; nested exception is org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
Caused by: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
Caused by: java.sql.SQLException: Unexpected exception while enlisting XAConnection java.sql.SQLException: XA error: XAResource.XAER_NOTA start() failed on resource 'weblogic.jdbc.jta.DataSource': XAER_NOTA : The XID is not valid
oracle.jdbc.xa.OracleXAException
Caused by: java.sql.SQLException: ORA-24756: transaction does not exist
这是我的第一个数据源的Spring配置:
@Configuration
@EnableJpaRepositories(basePackages = "my.primary.repository",
entityManagerFactoryRef = "primaryEntityManagerFactory")
public class PersistencePrimaryConfiguration {
@Bean
@Primary
@ConfigurationProperties(prefix="app.datasource.primary")
public DataSourceProperties primaryDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
public DataSource primaryDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource(primaryDataSourceProperties().getJndiName());
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(primaryDataSource())
.packages("my.primary.domain")
.persistenceUnit("primaryPU")
.build();
}
}
第二个:
@Configuration
@EnableJpaRepositories(basePackages = "my.secondary.repository",
entityManagerFactoryRef = "secondaryEntityManagerFactory")
public class PersistenceSecondaryConfiguration {
@Bean
@ConfigurationProperties(prefix="app.datasource.secondary")
public DataSourceProperties secondaryDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DataSource secondaryDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource(secondaryDataSourceProperties().getJndiName());
}
@Bean
public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondaryDataSource())
.packages("my.secondary.domain")
.persistenceUnit("secondaryPU")
.build();
}
}
在application.properties
:
app.datasource.primary.jndi-name=jdbc/primary
app.datasource.secondary.jndi-name=jdbc/secondary
主类使用@EnableTransactionManagement
注释:
@EnableTransactionManagement
public class MyApplication extends SpringBootServletInitializer {
}