通过使用@EnableAutoConfiguration和application.properties,还有另一种具有多个数据源的方法。
基本上,将多个dataSource配置信息放在application.properties上,并通过@EnableAutoConfiguration自动为第一个dataSource生成默认设置(dataSource和EntityManagerFactory)。但是对于下一个dataSource,请通过属性文件中的信息手动创建dataSource,entityManagerFactory和transactionManager。
下面是我设置两个数据源的示例。第一个数据源由@EnableAutoConfiguration设置,只能分配给一个配置,不能分配给多个。然后将通过DataSourceTransactionManager生成“ transactionManager” ,该外观看起来是由注释生成的默认transactionManager。但是,我已经看到,仅对于默认的DataSourceTransactionManager以及在有多个事务管理器的情况下,调度线程池中的线程上的事务才不会开始出现问题。所以我通过JpaTransactionManager手动创建transactionManager也为第一个dataSource分配了“ transactionManager” Bean名称和默认的entityManagerFactory。用于第一个数据源的JpaTransactionManager确实可以解决ScheduledThreadPool中线程上的奇怪事务问题。
Spring Boot 1.3.0.RELEASE的更新
我发现我以前使用@EnableAutoConfiguration的默认dataSource配置在使用Spring Boot 1.3版本查找entityManagerFactory时遇到问题。引入我自己的transactionManager之后,也许@EnableAutoConfiguration不会生成默认的entityManagerFactory。所以现在我自己创建了entityManagerFactory。因此,我不需要使用@EntityScan。因此,看起来我通过@EnableAutoConfiguration获得的安装越来越少。
第二个数据源是在没有@EnableAutoConfiguration的情况下设置的,并通过手动方式创建了“ anotherTransactionManager”。
由于从PlatformTransactionManager扩展了多个transactionManager,因此我们应在每个@Transactional注释上指定要使用的transactionManager
默认存储库配置
@Configuration@EnableTransactionManagement@EnableAutoConfiguration@EnableJpaRepositories( entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager", basePackages = {"com.mysource.repository"})public class RepositoryConfig { @Autowired JpaVendorAdapter jpaVendorAdapter; @Autowired DataSource dataSource; @Bean(name = "entityManager") public EntityManager entityManager() { return entityManagerFactory().createEntityManager(); } @Primary @Bean(name = "entityManagerFactory") public EntityManagerFactory entityManagerFactory() { LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); emf.setDataSource(dataSource); emf.setJpaVendorAdapter(jpaVendorAdapter); emf.setPackagesToScan("com.mysource.model"); emf.setPersistenceUnitName("default"); // <- giving 'default' as name emf.afterPropertiesSet(); return emf.getObject(); } @Bean(name = "transactionManager") public PlatformTransactionManager transactionManager() { JpaTransactionManager tm = new JpaTransactionManager(); tm.setEntityManagerFactory(entityManagerFactory()); return tm; }}另一个存储库配置
@Configuration@EnableTransactionManagement@EnableJpaRepositories( entityManagerFactoryRef = "anotherEntityManagerFactory", transactionManagerRef = "anotherTransactionManager", basePackages = {"com.mysource.anothersource.repository"})public class AnotherRepositoryConfig { @Autowired JpaVendorAdapter jpaVendorAdapter; @Value("${another.datasource.url}") private String databaseUrl; @Value("${another.datasource.username}") private String username; @Value("${another.datasource.password}") private String password; @Value("${another.dataource.driverClassName}") private String driverClassName; @Value("${another.datasource.hibernate.dialect}") private String dialect; public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(databaseUrl, username, password); dataSource.setDriverClassName(driverClassName); return dataSource; } @Bean(name = "anotherEntityManager") public EntityManager entityManager() { return entityManagerFactory().createEntityManager(); } @Bean(name = "anotherEntityManagerFactory") public EntityManagerFactory entityManagerFactory() { Properties properties = new Properties(); properties.setProperty("hibernate.dialect", dialect); LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); emf.setDataSource(dataSource()); emf.setJpaVendorAdapter(jpaVendorAdapter); emf.setPackagesToScan("com.mysource.anothersource.model"); // <- package for entities emf.setPersistenceUnitName("anotherPersistenceUnit"); emf.setJpaProperties(properties); emf.afterPropertiesSet(); return emf.getObject(); } @Bean(name = "anotherTransactionManager") public PlatformTransactionManager transactionManager() { return new JpaTransactionManager(entityManagerFactory()); }}application.properties
# database configurationspring.datasource.url=jdbc:h2:file:~/main-source;AUTO_SERVER=TRUEspring.datasource.username=saspring.datasource.password=spring.datasource.driver-class-name=org.h2.Driverspring.datasource.continueOnError=truespring.datasource.initialize=false# another database configurationanother.datasource.url=jdbc:sqlserver://localhost:1433;DatabaseName=another;another.datasource.username=usernameanother.datasource.password=another.datasource.hibernate.dialect=org.hibernate.dialect.SQLServer2008Dialect another.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
为@Transactional注释选择适当的transactionManager
第一数据源服务
@Service("mainService")@Transactional("transactionManager")public class DefaultDataSourceServiceImpl implements DefaultDataSourceService { //}为另一个数据源提供服务
@Service("anotherService")@Transactional("anotherTransactionManager")public class AnotherDataSourceServiceImpl implements AnotherDataSourceService { //}


