Jeśli ktoś ma ten problem, znalazłem rozwiązanie:
First twoi application.properties powinna wyglądać następująco:
datasource:
primary:
url: jdbc:mysql://localhost:3306/primary_db
username: your_username
password: your_password
driver-class-name: com.mysql.jdbc.Driver
secondary:
url: jdbc:mysql://localhost:3306/secondary_db
username: your_username
password: your_password
driver-class-name: com.mysql.jdbc.Driver
Po tym, trzeba utworzyć enum z baz danych:
public enum Database {
PRIMARY,
SECONDARY
}
Następnie należy utworzyć ThreadLocal:
public class DatabaseThreadContext {
private static final ThreadLocal<Database> current = new ThreadLocal<>();
public static void setCurrentDatabase(Database database) {
current.set(database);
}
public static Object getCurrentDatabase() {
return current.get();
}
}
Nadchodzi magiczny, trzeba użyć AbstractRoutingDataSource który został wdrożony na wiosnę 2 z powrotem w 2007 roku:
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DatabaseThreadContext.getCurrentDatabase();
}
}
Wreszcie wstrzyknąć konfigurację w swoim wiosennym Boot app:
@Configuration
public class DatabaseRouter {
@Bean
@ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public DataSource dataSource() {
Map<Object, Object> targetDatasources = new HashMap<Object, Object>(){{
put(Database.SECONDARY, secondaryDataSource());
put(Database.PRIMARY, primaryDataSource());
}};
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(primaryDataSource());
routingDataSource.setTargetDataSources(targetDatasources);
routingDataSource.afterPropertiesSet();
return routingDataSource;
}
}
W każdym żądaniu, jeśli chcesz zmienić bazę danych, skorzystaj z tej funkcji: DatabaseThreadContext.setCurrentDatabase(Database.PRIMARY);
.
Ponadto można mieć więcej niż dwie bazy danych w tym samym czasie.
Użyj aktywnych profili Spring w application.yml –
@Zubair Chcę używać obu jednocześnie iw zależności od sytuacji w mojej usłudze, wybierz jedną lub drugą. –
@JeanCedron To skomplikowana konfiguracja. Aby nie uchylać się od pytania, ale czy myślałeś o użyciu warstwy wiadomości, aby to ułatwić? Decider App podejmuje decyzję, do którego źródła danych się należy. Następnie wysyła wiadomość do kolejki specyficznej dla źródła danych, dla której węzeł roboczy odczytuje i utrwala dane. Tylko jedna myśl ... Zrobiłem kilka podwójnych aplikacji źródła danych, ale były one w pełni oddzielone pakietami pod względem encji, repozytoriów itp. –